ページ 11

BGMが止まらない

Posted: 2011年8月13日(土) 19:34
by whity
龍神録プログラミングの館をひと通り読み、シューティングゲームを作ったのですが、タイトル画面を作りたいと思い、
新・ゲームプログラミングの館3.3,3.4を参考にタイトル画面を作り、ゲームメイン画面でESCを押すとタイトル画面に戻るようにしたのですが、
タイトルに戻った時にBGMが鳴りやみません。また、ボスの弾幕が始まってから戻り、
またゲームをはじめるとボスのBGMがなり続け一面のBGMがなりません。

変更点は以下の通りです。

プロジェクトにtitle.cppを追加

コード:

#include "../include/GV.h"
#define MENU_MAX 5


// メニュー項目要素を5つ作る
        MenuElement_t MenuElement[MENU_MAX]={
                {  80, 100, "ゲームスタート" }, // タグの中身の順番で格納される。xに80が、yに100が、nameに"ゲームスタート"が
                { 100, 150, "おまけ" },
                { 100, 200, "ヘルプ" },
                { 100, 250, "コンフィグ" },
                { 100, 300, "ゲーム終了" },
        };
        

int calc_title(){

	if(CheckStatePad(configpad.down)==1){
		SelectNum = ( SelectNum + 1 ) % MENU_MAX; // 現在の選択項目を一つ下にずらす(ループする)
		se_flag[2]=1;
	}
	if(CheckStatePad(configpad.up) == 1 ){
		SelectNum = ( SelectNum + MENU_MAX-1 ) % MENU_MAX; // 現在の選択項目を一つ上にずらす(逆ループする)
		se_flag[2]=1;
	}
	if(CheckStateKey(KEY_INPUT_ESCAPE)==1 ){
		SelectNum = 4; 
		se_flag[2]=1;
	}
	
	if(CheckStatePad(configpad.down) >0 || CheckStatePad(configpad.up) >0 || CheckStateKey(KEY_INPUT_ESCAPE)>0){ // 下キーか、上キーが押された瞬間
			for( int i=0; i<MENU_MAX; i++ ){              // メニュー項目数である5個ループ処理
				if( i == SelectNum ){          // 今処理しているのが、選択番号と同じ要素なら
					MenuElement[i].x = 80; // 座標を80にする
				} else {                       // 今処理しているのが、選択番号以外なら
					MenuElement[i].x = 100;// 座標を100にする
				}
			}
	}
	
	//押しっぱなし処理
	if(CheckStatePad(configpad.down)>30 && CheckStatePad(configpad.down)%15==0){
			SelectNum = ( SelectNum + 1 ) % MENU_MAX; // 現在の選択項目を一つ下にずらす(ループする)
			se_flag[2]=1;
	}
	
	if(CheckStatePad(configpad.up)>30 && CheckStatePad(configpad.up)%15==0){
			SelectNum = ( SelectNum + MENU_MAX-1 ) % MENU_MAX; // 現在の選択項目を一つ上にずらす(ループする)
			se_flag[2]=1;
	}
	
	if(SelectNum==0 && CheckStatePad(configpad.shot)==1){
		PlaySoundMem(sound_se[4],DX_PLAYTYPE_BACK);
		WaitTimer(300);
		StopSoundMem(sound_se[4]);
		return 99;
	}
	if(SelectNum==4 && CheckStatePad(configpad.shot)==1){
		PlaySoundMem(sound_se[4],DX_PLAYTYPE_BACK);
		WaitTimer(300);
		return 1;
	}
	return 0;
}

void draw_title(){
	for( int i=0; i<MENU_MAX; i++ ){ // メニュー項目を描画
			DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );
	}
}

int title_main(){
	int sta=calc_title();
	draw_title();
	return sta;
}
GV.hに以下を追加
GLOBAL int SelectNum; // 現在の選択番号

function.hに以下を追加
GLOBAL int title_main();

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);//ウィンドウモード
	SetOutApplicationLogValidFlag( FALSE ) ;//logを出力しません
	SetWindowIconID(112) ;
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(ProcessLoop()==0){//メインループ
		music_ini();
		switch(func_state){
			case 0://初回のみ入る処理
				load();		//データロード
				first_ini();//初回の初期化
				func_state=96;
				break;
			case 96://title
				title_state=title_main();
				if(title_state){//title_stateが0でないなら
					if(title_state==1)goto QUIT;
					func_state=title_state;
				}
				break;	
			case 99://STGを始める前に行う初期化
				ini();
				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++;
				break;
			default:
				printfDx("不明なfunc_state\n");
				break;
		}
		music_play();              enter_func_tm("音楽再生");
		fps_wait();                enter_func_tm("待機した時間",1);
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1 && func_state==100){
			func_state=96;
			memset(&boss_shot , 0, sizeof(boss_shot_t));//弾情報初期化	
		}
		ScreenFlip();//裏画面反映
		count++;
	}
        QUIT:
	DxLib_End();//DXライブラリ終了処理
	return 0;
}

goto文使ってしまいました、すいません。

どなたかわかる方、ご回答よろしくお願いします。

Re: BGMが止まらない

Posted: 2011年8月13日(土) 22:45
by softya(ソフト屋)
こういうのはややこしいのでBGMを管理するモジュールで今鳴っているBGMを管理して、切り替えたり、停止させたりする関数群を作ったほうが管理しやすいです。

Re: BGMが止まらない

Posted: 2011年8月14日(日) 22:20
by whity
いろいろ試行錯誤していて

コード:

if(CheckStateKey(KEY_INPUT_ESCAPE)==1 && func_state==100){
			func_state=96;	
}

コード:

if(CheckStateKey(KEY_INPUT_ESCAPE)==1 && func_state==100){
			func_state=96;
			StopSoundMem(area.bgm.handle);
}
に変えると問題が解決しました。
皆さんご回答ありがとうございました。