ページ 11

EDへ移項の仕方

Posted: 2012年10月27日(土) 22:43
by @Ria
たびたびすいません…

コード:

#define GLOBAL_INSTANCE 
#include "../include/GV.h"

//ループで必ず行う3大処理
int ProcessLoop(){
	if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
	if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
	GetHitKeyStateAll_2();//現在のキー入力処理を行う
	GetHitPadStateAll();  //現在のパッド入力処理を行う
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	SetMainWindowText( "シューティングゲーム" ) ;
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
	while(ProcessLoop()==0){//メインループ
		music_ini();
		switch(func_state){
			case 0://music&movie
				PlayMovie( "../dat/img/title/op.avi" , 1.5 , DX_MOVIEPLAYTYPE_NORMAL ) ;
                PlaySoundFile("../dat/music/op.wav",DX_PLAYTYPE_LOOP );
				WaitTimer( 20 ) ;
				func_state=1;

				break;

			case 1://タイトル画面
				int Handle;
				//タイトル画像
				Handle = LoadGraph( "../dat/img/title/t1.png");
				DrawGraph(0,0,Handle,TRUE);
				//DrawString(100, 400, "スペースキーを押すと開始します", GetColor(255,255,255));
				if(CheckStateKey(KEY_INPUT_SPACE)==1)func_state=5;break;boss.flag=0;

			case 2://gameover
				DrawString(100, 400, "GAMEOVER スペースキーを押してね", GetColor(255,255,255));
				if(CheckStateKey(KEY_INPUT_SPACE)==1)
					func_state=6;
				PlaySoundFile("../dat/music/op.wav",DX_PLAYTYPE_LOOP );
				memset(enemy,0,sizeof(enemy_t)*ENEMY_MAX);
				memset(shot,0,sizeof(shot_t)*SHOT_MAX);
				memset(&boss_shot,0,sizeof(boss_shot_t));
				PlaySoundFile("../dat/music/op.wav",DX_PLAYTYPE_LOOP );
				break;

			case 6://タイトル画面
				int H;
				//タイトル画像
				H = LoadGraph( "../dat/img/title/t1.png");
				DrawGraph(0,0,H,TRUE);
				//DrawString(100, 400, "スペースキーを押すと開始します", GetColor(255,255,255));
				if(CheckStateKey(KEY_INPUT_SPACE)==1)func_state=5;break;boss.flag=0;

			case 5:
				int setu;
				setu = LoadGraph("../dat/img/title/setu.png");
				DrawGraph(0,0,setu,TRUE);
				if(CheckStateKey(KEY_INPUT_RETURN)==1)func_state=4;break;InitGraph() ;ClearDrawScreen() ;InitSoundMem() ;


			case 4://STGを始める前に行う初期化
				load();		//データロード
				first_ini();//初回の初期化
				ini();
				StopSoundFile();
				load_story();
				func_state=100;
				break;



			case 100://通常処理
								 enter_func_tm("最初");
				calc_ch();       enter_func_tm("キャラ計算");
				ch_move();       enter_func_tm("キャラ移動");
				cshot_main();    enter_func_tm("自機ショットメイン");
				enemy_main();	 enter_func_tm("敵処理メイン");
				boss_shot_main();enter_func_tm("ボスショットメイン");
				shot_main();	 enter_func_tm("ショットメイン");
				out_main();  	 enter_func_tm("当たり判定");
				effect_main();   enter_func_tm("エフェクトメイン");
				calc_main();	 enter_func_tm("計算メイン");
				graph_main();    enter_func_tm("描画メイン");
				bgm_main();		 enter_func_tm("BGMメイン");
				if(boss.flag==0)
					stage_count++;
				if()←ここになにかかけばいいのでしょうか?かくとして、どのような構文をかけばいいのでしょうか?
				


		}
		[b]PlayMovie( "../dat/img/title/ED.avi" , 1.5 , DX_MOVIEPLAYTYPE_NORMAL ) ;←これを再生させたいのです。[/b]
		break;
		music_play();			 enter_func_tm("音楽再生");
		fps_wait();				 enter_func_tm("待機した時間",1);
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
		ScreenFlip();//裏画面反映
		count++;
	}

	DxLib_End();//DXライブラリ終了処理
	return 0;
}
case 100でボスを倒したらED.aviを再生させたいのですがなかなか上手くいきません。このプログラムはmain.cppのコードです。
while文のループをぬけ、裏画面から表画面にして動画を再生する方法がよろしいのでしょうか?もし、それが可能でしたらアドバイスをください。違っていましたら別の方法を教えてください
よろしくお願いします

Re: EDへ移項の仕方

Posted: 2012年10月27日(土) 23:39
by Dixq (管理人)

本来であれば、メイン関数から各モジュールを呼ぶのではなく、GameManagerのようなモジュールを通して管理すべきなのでしょう。
今回は、ステージの管理モジュールが無いので表題の悩みが生じることと思います。
calc_mainが今似たようなことをやっていますが、こんな名前のモジュールは作るべきではないですね...(自分で言うのもなんですが)
ステージ管理のマネージャー的モジュールを用意し、そこがステージの管理をすべきでしょう。
もし今の造りのままで対応したいなら、calc_mainの中で特定のタイミング(ボスが死んだ瞬間EDになるのはおかしいので、タイマーを発火させて、ある程度たってから)でfunc_stateを101等にし、
case 101:
でED処理をすればよいかと思います。
func_stateも非常に不適切な変数名ですので、分かりやすい名前に変えた方が良いと思います。


if(boss.flag==0)
  stage_count++;

の部分がステージの変更を行っているのでしょうか?
各モジュールの初期化を行っていないので、このまま動くとも思えませんが・・。


このプログラムは正常に動作するのでしょうか?
if(CheckStateKey(KEY_INPUT_SPACE)==1)func_state=5;break;boss.flag=0;
特にこの辺、期待する動作になっているのでしょうか。


case 6:
等で毎フレームLoadGraphをやっているように見えますが、すごい勢いでメモリリークしていませんか?
毎回ロードする必要はあるのでしょうか。

Re: EDへ移項の仕方

Posted: 2012年10月28日(日) 00:58
by @Ria
一応、ゲームとして起動はしています。
1のcase 101をつかってEDをながしたいと思います

calc.cppのどこら辺をかきかえればいいのでしょうか?

Re: EDへ移項の仕方

Posted: 2012年10月28日(日) 01:27
by Dixq (管理人)
一つ訂正します。
>if(boss.flag==0)
>  stage_count++;

これは何ステージ目かを表すカウンタではなく、ステージ内のカウンタでしたね。私の方が誤解していました。

さて、何を持ってステージクリアとしますか?
実際はボスを倒した後、何らかの演出をしてからステージクリアとすべきでしょう。
そのためのタイマーの仕組みか何かが必要になると思いますが、一番簡単なやっつけの方法としてはstage_countによる比較があるかと思います。

ini.cppに
boss.appear_count[1]=2850;//最後ボスが出現する時刻(44)(47)
をしている部分がありますよね。
2850はボスが最後に出現する時刻です。
ボスが出現中はカウンタは止まっており、ボスが居なくなるとカウンタは進みます。
従ってカウンタが例えば2850+120とかになっている時にEDになれば、ボスを倒して2秒後にEDになることになります。
よって

if( stage_count == boss.appear_count[1] + 120 ){
    func_state = 101;
}

こんな感じで"とりあえず"出来ると思います。
こんなやっつけ対応を組み合わせていると破たんするでしょうが・・。

Re: EDへ移項の仕方

Posted: 2012年10月28日(日) 01:35
by @Ria
ありがとうございました!無事、EDをながすことができました

カウントを見逃していました…(汗

私はずっとbossのHPが0になったらEDにはいろうと悩んでおりました…


しかし、おかげで出来ました

ありがとうございました