画像表示と音楽演奏の並行

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

画像表示と音楽演奏の並行

#1

投稿記事 by moka315777 » 8年前

 どうも、お世話になっております。
 今回も質問させて頂きたいです。
 あまりにも初歩的な質問で恐縮なのですが……><

 現在開発中のゲームで、画像表示と音楽演奏を並行で行わせたいのですが、下記のプログラムで実行すると、音楽は演奏されるが、画像は表示されなくなります。 PlaySound関数の「NORMAL」の部分を「LOOP」にすれば、画像は表示されるが、音楽が途切れてしまいます。

 色々あがいてみましたが、どうしようもできません。
 コードを転載させて頂きますので、是が非でも助言をお願い申し上げますm(_)m
 

コード:


#include "DxLib.h"



// プログラムは WinMain から始まります

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{
	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	
	}


	// ウインドウモードに変更
	ChangeWindowMode( TRUE ) ;

	// タイトルを test に変更
	SetMainWindowText( "ねむれんの愉快な冒険" ) ;




	char Key[256] ;



	 int titleGraph ;

	int titleX , titleY ;

	

	

			

	

	

	 while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){

            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了


		 	// test.midのバックグラウンド演奏
	PlaySound( "title.wav" , DX_PLAYTYPE_NORMAL ) ;


		 // 画面を初期化(真っ黒にする)
		ClearDrawScreen() ;


		
		

		
		 
			
	


		 // グラフィックの描画先を裏画面にセット
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// ねむれんのグラフィックをメモリにロード&表示座標をセット
	titleGraph = LoadGraph( "title.png" ) ;
	titleX = 7 ; titleY = 10 ;



	



		
			
		

		
		 if( CheckHitKey(KEY_INPUT_Z) == 0  ){
	
		 

			  

			


		

		

 

	

			

	


	

	DrawGraph( titleX , titleY , titleGraph , TRUE ) ;


	SetFontSize( 40 ) ;                             //サイズを20に変更
        SetFontThickness( 1 ) ;                         //太さを1に変更
        ChangeFont( "HGS創英角ポップ体" ) ;              //HGS創英角ポップ体に変更
        ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
 
 
        DrawString(200,320,"ねむれんの愉快な冒険",GetColor(255,255,255));


		 SetFontSize( 20 ) ;                             //サイズを20に変更
        SetFontThickness( 1 ) ;                         //太さを1に変更
        ChangeFont( "HGS創英角ポップ体" ) ;              //HGS創英角ポップ体に変更
        ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更



 
		
		


		

	 


         DrawFormatString( 200, 400, GetColor(0,0,255), "Zキーでスタート!" );

		DrawFormatString( 200, 420, GetColor(0,0,255), "(c) moka" );

					

		// 裏画面の内容を表画面にコピーする
		ScreenFlip() ;

		
		
		
	
		 
	
		 }
		 
		

		 
		 

			if( CheckHitKey(KEY_INPUT_Z) == 1  ){


				StopSoundFile();


					// グラフィックの描画先を裏画面にセット
	SetDrawScreen( DX_SCREEN_BACK ) ;


				


	DrawFormatString( 200, 200, GetColor(0,0,255), "その夜……ねむれんは、夢を見ていた……" );


			

	
        // 裏画面の内容を表画面にコピーする
		ScreenFlip() ;
		
			}   
				    


		

                
	 }

	
			
			










if(titleX==500){



DxLib_End() ; // DXライブラリ使用の終了処理

return 0 ; // ソフトの終了

} }

naohiro19
記事: 256
登録日時: 9年前
住所: 愛知県

Re: 画像表示と音楽演奏の並行

#2

投稿記事 by naohiro19 » 8年前

毎回ループでPlaySoundFileを読み込んでるので途切れますので
LoadGraphと同じく LoadSoundMemで読み込んで PlaySoundMemでループ再生をすれば途切れることなく再生できるはずです。

beatle
記事: 1280
登録日時: 8年前
住所: 埼玉
連絡を取る:

Re: 画像表示と音楽演奏の並行

#3

投稿記事 by beatle » 8年前

質問への答えではありませんが、ソースコードについて。
  • いくらなんでも空行が多すぎませんか?(そういうコーディングスタイルなのでしょうか?)
  • インデント(字下げ)が揃っていません。
  • 最後のほうがcodeタグからはみ出ています。
インデントを揃えるというのも一つの技術ですから、頑張って習得してください。

hss12
記事: 40
登録日時: 8年前

Re: 画像表示と音楽演奏の並行

#4

投稿記事 by hss12 » 8年前

いろいろ問題があります。
ゲームプログラミングの館
http://dixq.net/g/index.html
をよく読んでみることをお勧めします。

とりあえず、
ウインドウモードに変更はDXライブラリ初期化処理より先に書いてください。
一度フルスクリーンになってしまいます。

// グラフィックの描画先を裏画面にセット
SetDrawScreen( DX_SCREEN_BACK ) ;
は一度だけ書けばよいのでwhileのループより前に書きます。

// 画面を初期化(真っ黒にする)
ClearDrawScreen() ;
はwhileの()の中にすでに書かれているのでまた書く必要はありません。

// 裏画面の内容を表画面にコピーする
ScreenFlip() ;
もwhileループの最後に1度だけ書けば良いです。2回書いてはいけません。


titleGraph = LoadGraph( "title.png" ) ;
としているのは良いのですが、whileループは1秒間におそらく60回繰り返されているので
何度も画像を読み込んでいることになります。whileより上に書きましょう。同じく音楽もです。
しかし、何度も最初から音楽を再生しようとしてしまうため音楽が先に進みません。
音楽を再生する処理をするかフラグを立てておく必要があります。
あるいは
PlaySoundMem( titleMusic, DX_PLAYTYPE_BACK, FALSE );
これでも問題なく再生されます。
FALSEにすると途中から再生する処理になります。
書かない場合は音楽を最初から再生しようとするため、whileの中に書いた場合、音楽が鳴りません。
ただし、同じ音楽を後でまた使う場合、途中からの再生になってしまうのでフラグを立てたほうが良いでしょう。

フォントの変更で同じことを書いていますが
この場合同じフォントなので2回目に書くのはSetFontSize( 20 );だけで良いです。
このフォント変更の処理も1秒間におそらく60回繰り返されてしまうので
1回だけになるようフォント変更用stateを作るなど工夫してください。

最後の if(titleX==500) は何なのでしょうか。
whileより下なのでこの式は終了処理をしたときに実行されますが
titleXが500ではないため DxLib_End(); が実行されずプログラムが異常終了してしまいます。


あと全体的にスペースが多いのはともかく
// タイトルを test に変更
SetMainWindowText( "ねむれんの愉快な冒険" );

// test.midのバックグラウンド演奏
PlaySound( "title.wav" , DX_PLAYTYPE_NORMAL );

SetFontSize( 40 ); //サイズを20に変更
など説明コメントとプログラムがやっている内容が違います。直すようにしましょう。


色もこれだけ書くなら最初に宣言してしまったほうが楽かもしれないですね。
文字も直に入力するのではなく配列などデータベースをつくりstateなどを変化させて
表示する文字が変わっていくように書いたほうが良いでしょう。(この処理は下のコードには書きませんでしたが)


以下少し直してみました。これもそんなに良いコードではありませんが
自分のコードと見比べて考えてみてください。

コード:

#include "DxLib.h"

// プログラムは WinMain から始まります

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	ChangeWindowMode( TRUE ); // ウインドウモードに変更
    if ( DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK ) != 0 ) return -1; //DXライブラリ初期化処理と描画先を裏画面にセット
	SetMainWindowText( "ねむれんの愉快な冒険" );	// タイトルを変更
	
	int color[8];
	color[0] = GetColor(255,255,255); //白
	color[1] = GetColor(  0,  0,  0); //黒
	color[2] = GetColor(255,  0,  0); //赤
	color[3] = GetColor(  0,255,  0); //緑
	color[4] = GetColor(  0,  0,255); //青
	color[5] = GetColor(255,255,  0); //黄色
	color[6] = GetColor(  0,255,255); //青緑
	color[7] = GetColor(255,  0,255); //紫

	char Key[256];

	int titleX, titleY;
	int state;
	int stateMusic;
	int titleGraph;
	int titleMusic;

	state = 0; //キーが押されたか
	stateMusic = 0; //音楽を再生する処理を行うか 0なら再生する
	titleX = 7 ; titleY = 10 ; // ねむれんのグラフィックの表示座標をセット
	titleGraph = LoadGraph( "title.png" ) ; // ねむれんのグラフィックをメモリにロード
	titleMusic = LoadSoundMem("title.wav"); // サウンドtitle.wavをメモリにロード


	//ここから繰り返し開始
	while( !ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] ){
			//↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了

		if ( stateMusic == 0 ){
			PlaySoundMem( titleMusic, DX_PLAYTYPE_BACK ); // 音楽のバックグラウンド再生
			stateMusic = 1; //再生する処理をした場合は1になり次のループでは実行されなくなる
			//stateMusicを0にすればまた再生される
			//BGMにするなら DX_PLAYTYPE_BACK より DX_PLAYTYPE_LOOPの ほうが良いかも
		}
		
		if( CheckHitKey(KEY_INPUT_Z) == 1 ){
			state = 1; //zキーが押されるとstateが1になる
		}

		if ( state == 0 ){
			DrawGraph( titleX , titleY , titleGraph , TRUE ); //画像を表示

			SetFontSize( 40 ); //サイズを40に変更
			SetFontThickness( 1 ); //太さを1に変更
			ChangeFont( "HGS創英角ポップ体" ); //HGS創英角ポップ体に変更
			ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE ); //アンチエイリアス&エッジ付きフォントに変更
			DrawString(200,320,"ねむれんの愉快な冒険", color[0] );

			SetFontSize( 20 ); //サイズを20に変更			
			DrawFormatString( 200, 400, color[4], "Zキーでスタート!" );
			DrawFormatString( 200, 420, color[4], "(c) moka" );
		}

		if( state == 1 ){
			StopSoundMem( titleMusic ) ; //titleMusicの再生を止める
			DrawFormatString( 200, 200, color[4], "その夜……ねむれんは、夢を見ていた……" );
		}

		if( CheckHitKey(KEY_INPUT_X) == 1 ){
			state = 0; //xキーが押されるとstateが0になりタイトル画面に戻る
			stateMusic = 0; //音楽を再生させる
		}

		ScreenFlip(); //裏画面の内容を表画面にコピーする (2回書いてはいけない)
		//ここまでが繰り返し whileへ戻る
	}

	//以下終了したときの処理
	DxLib_End(); // DXライブラリ使用の終了処理
	return 0; // ソフトの終了 
}

閉鎖

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