ノベルゲームの音楽ファイルの再生について、二回目

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ゴンマサ

ノベルゲームの音楽ファイルの再生について、二回目

#1

投稿記事 by ゴンマサ » 12年前

以前同じ質問をしたものです。
こちらを参考にして作成しております。
http://www.usamimi.info/~guiprog/game/

あれからスクリプト言語を改良し、前よりは簡潔な記述にできたのですが、どうもうまくいきません。
音楽ファイルの再生をループに入る前に行う方法が思いつかなかったため
whileの中にgotoやcontinueを使ってみたのですが音楽が再生されませんでした。
ヒントなどいただければと思います。
よろしくお願いいたします。

音楽ファイルを読み込む際のスクリプト言語(抜粋)

コード:

 
		//音楽ファイルをメモリに読み込む
	}else if( strncmp(message[0], "@@loadmusic", SCRIPT_MAX_STRING_LENGTH) == 0 ) { 
		LoadMusicFile(message[1]);//1は音楽ファイル名

		//音楽ファイルを停止・削除
	}else if (strncmp(message[0], "@@stopmusic", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
		StopPlayMusic() ;

 


音楽ファイルの再生に関するヘッダー

コード:

 
#include "DxLib.h"

static int M_Memory;//音楽ファイルのメモリ

void LoadMusicFile(const char*musicFilename);//音楽ファイルを読み込むための記述
void PlayMusic();//音楽ファイルを再生するための記述

void StopPlayMusic();//StopMusicではDXライブラリのリファレンスに存在しているため重複を避ける





音楽ファイルの再生に関するソース

コード:

 
#include "music.h"



//音楽ファイルを読み込む記述
void LoadMusicFile(const char* musicFilename)
{
    M_Memory = LoadSoundMem(musicFilename);
}


//音楽ファイルを再生する記述
void PlayMusic()
{
	PlaySoundMem(M_Memory , DX_PLAYTYPE_LOOP );
}


//再生されている音楽ファイルを停止・メモリから削除する
void StopPlayMusic()
{
	StopSoundMem( M_Memory );
	DeleteSoundMem( M_Memory );
}




gotoを使った場合のループの記述

コード:

 
int Game_Draw(){

//DxLib初期化
if( DxLib_Init() == -1 ) {
		 return -1;
}
	initGame();
			ClearDrawScreen() ;

         MUSIC:

		PlayMusic();


	//ここからメインループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_E ) == 0 ) {
		

		//画面クリア
		ClearDrawScreen();

		if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) {
			//マウス押しっぱなしの時にスクリプトがどんどん進まないようにする
			if( GetNowCount() - g_mouseClickedTime > 500 ) { 
				//キー入力待ちを解除
				unsetWaitKeyInput();
				//マウスクリックした時間を取得
				g_mouseClickedTime = GetNowCount();
			}
		}
		



		//スクリプト言語の解析
		if( getWaitKeyInput() != WAIT_UNTIL_KEY_INPUT &&
			getWaitSelectBoxInput() != WAIT_UNTIL_KEY_INPUT ) {
			decodeScript( g_script.script[ g_script.currentLine ], &g_script );
			g_script.currentLine++;
		}
		//スクリプトを解析して、それぞれの対応した場所に命令を出し、それをループの中に返している

		//画像描画・craphic.cppからの命令を実行
		drawVisibleGraphic();
		//メッセージ描画・Message.cppからの命令を実行
		drawMessage();
		//音楽ファイルの再生を停止、メモリから削除

		StopPlayMusic();

		Sleep(10);

		ScreenFlip();

		//音楽ファイルが再生されている場合は
		//以下の記述を省略しループの先頭に戻る
		if(CheckSoundMem( M_Memory ) == 0)

			
			goto MUSIC;



	}//ループの終わり

	DxLib_End();//継続条件が満たされなくなったとき
	return 0;

}



continueを使った場合のループの記述(ソースやヘッダーの記述はgotoの時と同じです)

コード:

 
int Game_Draw(){

//DxLib初期化
if( DxLib_Init() == -1 ) {
		 return -1;
}
	initGame();

	//ここからメインループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_E ) == 0 ) {
		

		//画面クリア
		ClearDrawScreen();

		if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) {
			//マウス押しっぱなしの時にスクリプトがどんどん進まないようにする
			if( GetNowCount() - g_mouseClickedTime > 500 ) { 
				//キー入力待ちを解除
				unsetWaitKeyInput();
				//マウスクリックした時間を取得
				g_mouseClickedTime = GetNowCount();
			}
		}
		



		//スクリプト言語の解析
		if( getWaitKeyInput() != WAIT_UNTIL_KEY_INPUT &&
			getWaitSelectBoxInput() != WAIT_UNTIL_KEY_INPUT ) {
			decodeScript( g_script.script[ g_script.currentLine ], &g_script );
			g_script.currentLine++;
		}
		//スクリプトを解析して、それぞれの対応した場所に命令を出し、それをループの中に返している

		//画像描画・craphic.cppからの命令を実行
		drawVisibleGraphic();
		//メッセージ描画・Message.cppからの命令を実行
		drawMessage();
		//音楽ファイルの再生を停止、メモリから削除

		StopPlayMusic();

		Sleep(10);

		ScreenFlip();
		//音楽ファイルが再生されている場合は
		//以下の記述を省略しループの先頭に戻る
		if(CheckSoundMem( M_Memory ) == 1)

			
			continue;


		PlayMusic();





	}//ループの終わり

	DxLib_End();//継続条件が満たされなくなったとき
	return 0;

}


 

以上になります。
よろしくお願いいたします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ノベルゲームの音楽ファイルの再生について、二回目

#2

投稿記事 by softya(ソフト屋) » 12年前

本題の問題では無いのですが、インデントが狂っていて読みづらいのとGame_Draw()でロジックを書くという名前と機能が違うと言うお約束違反をしているので改めて頂くと読みやすくなります。あと、Sleepもいらないです。
StopPlayMusic();がある位置も謎なので、どういう流れを意図しているのか簡易的に書いていただけますでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ゴンマサ

Re: ノベルゲームの音楽ファイルの再生について、二回目

#3

投稿記事 by ゴンマサ » 12年前

softya(ソフト屋)様
返信ありがとうございます。
Game_Drawについては、ビルドが通れば名称はなんでもよいと思っておりました。
改めて記載させていただきます。
流れについては


continueの場合


・ループが始まったらスクリプト言語を解析して、それぞれの命令を実行する
・画像を描画する・・・drawVisibleGraphic();
・文章を描画する・・・drawMessage();
・音楽ファイルが停止している場合はcontinueを超えて音楽ファイルを再生する・・・ PlayMusic();
・ループの先頭に戻る
・以下、音楽ファイルが再生されている場合はcontinueを有効とし、ループの先頭に戻る
・音楽の再生を止めるときは、StopPlayMusicによって音楽ファイルの再生を止め、メモリから削除する
・以降は、再度音楽ファイルの読み込みが行われるまでcontinueによる省略は行われないものの、 PlayMusicの記述は無視されてループが継続される

以上がcontinueを使って作ろうとした流れでした。


コード:

 
int Game(){
 
//DxLib初期化
if( DxLib_Init() == -1 ) {
return -1;
}
initGame();
 
//ここからメインループ
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_E ) == 0 ) {
        
 
//画面クリア
ClearDrawScreen();
 
if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) {
//マウス押しっぱなしの時にスクリプトがどんどん進まないようにする
if( GetNowCount() - g_mouseClickedTime > 500 ) { 
//キー入力待ちを解除
unsetWaitKeyInput();
//マウスクリックした時間を取得
g_mouseClickedTime = GetNowCount();
}
}
        
 
 
 
//スクリプト言語の解析
if( getWaitKeyInput() != WAIT_UNTIL_KEY_INPUT &&
getWaitSelectBoxInput() != WAIT_UNTIL_KEY_INPUT ) {
decodeScript( g_script.script[ g_script.currentLine ], &g_script );
g_script.currentLine++;
}
//スクリプトを解析して、それぞれの対応した場所に命令を出し、それをループの中に返している
 
//画像描画・craphic.cppからの命令を実行
drawVisibleGraphic();
//メッセージ描画・Message.cppからの命令を実行
drawMessage();
//音楽ファイルの再生を停止、メモリから削除
 
StopPlayMusic();
 
 
ScreenFlip();
//音楽ファイルが再生されている場合は
//以下の記述を省略しループの先頭に戻る
if(CheckSoundMem( M_Memory ) == 1)
      
continue;
 
PlayMusic();
 
 
}//ループの終わり
 
DxLib_End();//継続条件が満たされなくなったとき
return 0;
 
}


これでは再生されなかったため、ループの外で音楽ファイルを再生する命令を出すようにしました。

gotoの場合

・ループに入る前のPlayMusicでは、最初は音楽ファイルをロードしていないためスルーされる
・ループが始まったらスクリプト言語を解析して、それぞれの命令を実行する
・画像を描画する・・・drawVisibleGraphic();
・文章を描画する・・・drawMessage();
・音楽ファイルが停止している場合はgotoが有効となり、ループの前のラベルに戻る
・この時点で音楽ファイルが読み込まれていれば、PlayMusicの記述にて再生され、
 StopPlayMusicによって再生が停止、メモリから削除されるまでループする。
・音楽ファイルををStopPlayMusicによって停止、削除した場合はgotoが有効となり、
 再び音楽ファイルが読み込まれるまでループを出入りする。

コード:

 
int Game(){
 
//DxLib初期化
if( DxLib_Init() == -1 ) {
         return -1;
}
initGame();
ClearDrawScreen() ;
 
MUSIC:
 
PlayMusic();
 
 
//ここからメインループ
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_E ) == 0 ) {
        
 
//画面クリア
ClearDrawScreen();
 
if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) {
            //マウス押しっぱなしの時にスクリプトがどんどん進まないようにする
if( GetNowCount() - g_mouseClickedTime > 500 ) { 
//キー入力待ちを解除
unsetWaitKeyInput();
//マウスクリックした時間を取得
g_mouseClickedTime = GetNowCount();
}
}
        
 
 
 
//スクリプト言語の解析
if( getWaitKeyInput() != WAIT_UNTIL_KEY_INPUT &&
getWaitSelectBoxInput() != WAIT_UNTIL_KEY_INPUT ) {
decodeScript( g_script.script[ g_script.currentLine ], &g_script );
g_script.currentLine++;
}
//スクリプトを解析して、それぞれの対応した場所に命令を出し、それをループの中に返している
 
//画像描画・craphic.cppからの命令を実行
drawVisibleGraphic();
//メッセージ描画・Message.cppからの命令を実行
drawMessage();
//音楽ファイルの再生を停止、メモリから削除
 
StopPlayMusic();
 
 
ScreenFlip();
 
//音楽ファイルが再生されている場合は
//以下の記述を省略しループの先頭に戻る
if(CheckSoundMem( M_Memory ) == 0)
 
            
goto MUSIC;
 
 
 
}//ループの終わり
 
DxLib_End();//継続条件が満たされなくなったとき
return 0;
 
}
 
以上が意図した内容になります。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ノベルゲームの音楽ファイルの再生について、二回目

#4

投稿記事 by softya(ソフト屋) » 12年前

元のコードも見ましたが、script.cppから音楽の管理モジュール(music.cppなどの名前のモジュール)に再生開始や停止などを依頼するだけで良い様に思います。
どうしてもメインループから呼ぶ必要があるとしても、呼び出すのは独自関数のmusicUpdate()関数ぐらいにしてmusicUpdate()関数の内部で制御すべきです。
今回のコードはメインループに無理に展開しようとするから複雑な制御になっているんでは無いでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ゴンマサ

Re: ノベルゲームの音楽ファイルの再生について、二回目

#5

投稿記事 by ゴンマサ » 12年前

返信ありがとうございます。
音楽ファイル関連の記述をループ内に記述せず、Musicソース内で完結するようにしたところ音楽を流すことができました。
とても助かりました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る