ページ 11

フェードイン・フェードアウトの処理について

Posted: 2015年2月28日(土) 10:28
by けんい
先日の紅魔郷のタイトルについてはありがとうございました。
無事タイトルを作れたのはいいのですがキーを押すと瞬時に画面が変わってしまいます。
そこで”http://homepage2.nifty.com/natupaji/DxL ... am.html#N9
を参考にこのようなコードを組みました。(変更したのは48行目~59行目です)

main.cpp

コード:

#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);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

    while(ProcessLoop()==0){//メインループ

		static int sel = 0;//追加
		int i ;
        static int x = 500 ,y = 100;//追加
		static int title = LoadGraph("../dat/title.png"); // タイトル画像ハンドル
		static int title2 = LoadGraph("../dat/titlea.png"); // タイトル画像ハンドル
		static int title3 = LoadGraph("../dat/loading.png"); // タイトル画像ハンドル
 
		music_ini();
        switch(func_state){
            case 0://初回のみ入る処理
                load();     //データロード
                first_ini();//初回の初期化
                func_state=10;//ここを10に
                break;
            case 10://STGを始める前に行う初期化
                ini();
                load_story();
                func_state=11;//メニューへ
                break;
			case 11://説明(注意書き)
				DrawGraph( 0 , 0 , title3 , FALSE ) ;      //タイトル表示
				if(CheckStateKey(KEY_INPUT_Z)==1)
                {
					 PlaySoundFile("../dat/konjaku.wav",DX_PLAYTYPE_LOOP);
                    if(sel == 0)
                        func_state=20;
                }
                break;
            case 20://メニュー1
				// 時間待ち
				WaitTimer( 1000 ) ;

				for( i = 0 ; i < 255 ; i ++ )
				{
					// 描画輝度をセット
					SetDrawBright( i , i , i ) ;
		
					// グラフィックを描画
					DrawGraph( 0 , 0 , title , FALSE ) ;
					ScreenFlip() ;
				}
				
                if(CheckStateKey(KEY_INPUT_UP)==1)
                {
                    if(sel < 1)
                        func_state=21;
                }
                if(CheckStateKey(KEY_INPUT_DOWN)==1)
                {
                    if(sel < 1)
                        func_state=21;
                }
                if(CheckStateKey(KEY_INPUT_Z)==1)
                {
                    if(sel == 0)
                        func_state=100;
					StopSoundFile() ;
                }
                break;
			case 21://メニュー2
				DrawGraph( 0 , 0 , title2 , FALSE ) ;      //タイトル表示

                if(CheckStateKey(KEY_INPUT_UP)==1)
                {
                    if(sel < 1)
                        func_state=20;
                }
                if(CheckStateKey(KEY_INPUT_DOWN)==1)
                {
                    if(sel < 1)
                        func_state=20;
                }
                if(CheckStateKey(KEY_INPUT_Z)==1)
                {
                    if(sel == 0)
                        func_state=100;
                }
                break;
            case 100://通常処理
                calc_ch();   //キャラクタ計算
                ch_move();   //キャラクタの移動制御
                cshot_main();//自機ショットメイン
				enemy_main();//敵処理メイン
				shot_main(); //ショットメイン
				boss_shot_main();
				out_main();  //当たり計算
				effect_main();//エフェクトメイン
                graph_main();//描画メイン
				if(boss.flag==0)
	                stage_count++;
                break;
            default:
                printfDx("不明なfunc_state\n");
                break;
        }
		music_play();
        if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
        ScreenFlip();//裏画面反映
		count++;
    }

    DxLib_End();//DXライブラリ終了処理
    return 0;
}
case11からcase20への移り変わり(48行目~59行目)にフェードイン処理を入れたのですが
だんだん明るくなる処理が繰り返されてしまいます。
また、その間キー入力も受け付けません。
そこで処理を繰り返さないようにする方法を教えていただきたいです。

環境は
Windows7 64bit
コンパイラ名 : VC++ 2008EE

どの程度C言語を理解しているかですが
初めて1ヶ月ぐらいであるためあまり理解できていないです。

言語はC言語です。

Re: フェードイン・フェードアウトの処理について

Posted: 2015年2月28日(土) 11:29
by Rittai_3D
http://dixq.net/g/h_11.htmlに書いてある
不適切な実装3. あちこちにDXライブラリ3大処理がある
に反しています。ScreenFlip()は一度だけ呼び出すようにしましょう。

また、コードが長くなっているので関数分けした方が良いと思います。

キーが押されたらフェードイン•フェードアウトステートに移動して、フェードイン•フェードアウトが終わったらメニュー画面に遷移するようにすれば良いと思います。

Re: フェードイン・フェードアウトの処理について

Posted: 2015年2月28日(土) 11:52
by けんい
返信ありがとうございます。
キーが押されたらフェードイン•フェードアウトステートに移動して、フェードイン•フェードアウトが終わったらメニュー画面に遷移するようにすれば良いと思います。
その手があったんですね。
実装した方法としてはフェードイン•フェードアウト用のcaseを作り、時間がたったら移動するようにしました。
Rittai_3D  様 紅魔郷のタイトルの件とこの件どちらにも的確なアドバイスをしていただきありがとうございました。

Re: フェードイン・フェードアウトの処理について

Posted: 2015年2月28日(土) 14:05
by Dixq (管理人)
3Dさん同様

http://dixq.net/g/h_11.htmlに書いてある
不適切な実装2. WaitやSleepを行っている。

にも該当してしまっています。
Sleepするとすべての処理が止まってしまうのでゲームプログラミングでは禁じ手です。
カウンターを使って時間を測るか、ループを回しながら時間を測定して次の段階へ進むように改善した方がよいですよ。

Re: フェードイン・フェードアウトの処理について

Posted: 2015年3月01日(日) 17:54
by けんい
返信遅れてすいません
Dixq 様 指摘ありがとうございます。
気をつけるようにします。