ページ 11

選択画面

Posted: 2010年3月13日(土) 00:02
by rolf
以下のソースに、カーソルがニューゲームになっているところでエンターキーを押すと、1.mp3 が流れるようにするにはどうしたらいいのでしょうか?






#include "DxLib.h"

int GetHitKeyStateAll_2(int KeyStateBuf[/url]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key==1) KeyStateBuf++;
else KeyStateBuf=0;
}
return 0;
}

void char_disp(int White,int y){
DrawString( 150 , y , "■" , White );
DrawString( 170 , 100 , "NEW GAME" , White );
DrawString( 170 , 120 , "CONTINUE1" , White );
DrawString( 170 , 140 , "CONTINUE2" , White );
DrawString( 170 , 160 , "CONTINUE3" , White );
DrawString( 170 , 180 , "CONTINUE4" , White );
DrawString( 170 , 200 , "CONTINUE5" , White );
DrawString( 170 , 220 , "CONTINUE6" , White );
DrawString( 170 , 240 , "LOG OUT" , White );
}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

int Key[256];
int White , y=100; //色とy座標の宣言

ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

White = GetColor( 255 , 255 , 255 ) ; //色の取得


while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存       ↑ESCが押されていない

char_disp(White,y); // 文字を描画

if( Key[KEY_INPUT_DOWN]==1 ||( Key[KEY_INPUT_DOWN]%5==0 && Key[KEY_INPUT_DOWN]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y+=20;
if(y==260) // y座標が260なら(選択が一番下なら)
y=100; // 選択座標を一番上に
}

ScreenFlip();//裏画面反映
}

DxLib_End();
return 0;
}

Re:選択画面

Posted: 2010年3月13日(土) 02:24
by kazuoni
まずひとつずつ解決していきましょう。

1. 音声ファイルを読み込み、再生するプログラムを作ってみる
2. y座標がNEW GAMEのところでエンターキーが押されたらの条件分岐を加える
3. 1と2を融合させればできあがり

1.については関数LoadSoundMem→関数PlaySoundMemの流れでOKです。
詳しくは本家をご覧ください。
ttp://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_sound.html#R8N5

2.については、今回ならば「y==100」の時かつ「エンターキーが押された瞬間」
という条件分岐を加えるだけです。

難しい事ではないと思うのでゆっくり考えながら実現してみてください。

Re:選択画面

Posted: 2010年3月13日(土) 22:03
by rolf
2.については、今回ならば「y==100」の時かつ「エンターキーが押された瞬間」
という条件分岐を加えるだけです。



というのは



if ( y == 100 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) {

PlaySoundMem関数を使う




でオーケーですか?

Re:選択画面

Posted: 2010年3月13日(土) 22:39
by rolf
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存       ↑ESCが押されていない

char_disp(White,y); // 文字を描画

if( Key[KEY_INPUT_DOWN]==1 ||( Key[KEY_INPUT_DOWN]%5==0 && Key[KEY_INPUT_DOWN]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y+=20;
if(y==260) // y座標が260なら(選択が一番下なら)
y=100; // 選択座標を一番上に
}

ScreenFlip();//裏画面反映
}

DxLib_End();
return 0;
}




の while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存       ↑ESCが押されていない

の下にその文を入れてみたのですが、エラーは出ないのですが音がでませんでした・・・どうしたらいいですかね?

Re:選択画面

Posted: 2010年3月13日(土) 22:45
by ideyan
>if ( y == 100 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) {
>PlaySoundMem関数を使う
>}

条件がエンターキーでなくエスケープキーになっていませんか?

あと、上の条件では押している間PlaySoundMemが呼ばれてしまうので

if ( y == 100 && Key[KEY_INPUT_RETURN]==1 )

このようにして押しっぱなし対策をした方がいいかと思います。 画像

Re:選択画面

Posted: 2010年3月14日(日) 00:22
by rolf
このようにして押しっぱなし対策をした方がいいかと思います。


というのは エンターキーをポチッと押すと音がながれるのではなくて 押している間だけながれてくるのですか?

Re:選択画面

Posted: 2010年3月14日(日) 01:37
by ideyan
あぁ、よく考えるとエンターキー押して画面遷移させてしまうなら
あまり関係ないかもしれません^^;

とりあえず、今のような画面遷移をしない状況で押しっぱなし対策をしないと、
エンターキーを押している間は毎ループPlaySoundMemが呼ばれることになります。

DX_PLAYTYPE_NORMALを指定すれば再生が終わるまで待機する(?)ので多分問題は起こりません。
(多分と言うのは、最近DXライブラリを触っていないので自信が無いからですorz)

DX_PLAYTYPE_BACKを指定すると、音の再生が終わるのを待たずに処理は進んでいきます。
この状況で次のループで再度PlaySoundMemが呼ばれると、
再生中の音はそのままで、さらにもう一つ再生が行われてしまいます。
勿論、用途によってはわざとそういう作りにする場合もあります。

押しっぱなし対策をしない場合、
プログラムの構成によってはキーを押している間ずっと新規の再生処理が行われてしまう。
というのが前回私の言いたかったことです(わかりにくくてすいません^^;)

色々言っといて何ですが、こういうのは聞くより先に
実際に試してみるのが一番わかりやすいかもしれません。

Re:選択画面

Posted: 2010年3月14日(日) 03:03
by kazuoni
キー監査で関数GetHitKeyStateAll_2を使用しているならば、
押しっぱなし対策は考えなくてもよいかと思います。
Key[/url]==1となるときは押された瞬間のみですので。
(以降はインクリメントされる)

押したら音が流れるだけでよいならideyanさんが提示して下さった
if ( y == 100 && Key[KEY_INPUT_RETURN]==1 )
でOKです。

押している間だけながれてくるようにしたいならば、
同様に、入力があったら再生を開始し、
毎ループKey[/url]>0かどうかを調べ、Key[/url]==0になったならば
関数StopSoundMemで止めればよいかと思います。

Re:選択画面

Posted: 2010年3月14日(日) 13:36
by rolf
何度もすいません・・・

if ( y == 100 && Key[KEY_INPUT_RETURN]==1 )

はどこにいれたらいいのでしょうか??

Re:選択画面

Posted: 2010年3月14日(日) 14:06
by rolf
再生はできたのですが、停止ができません・・・ 以下のソースをみてください



~~~~~~~~~~~~略~~~~~~~~~~~~

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存       ↑ESCが押されていない

char_disp(White,y); // 文字を描画

if ( y == 100 && Key[KEY_INPUT_RETURN]==1 ){

PlayMusic( "1.mp3" , DX_PLAYTYPE_BACK );

while( CheckMusic() == 1 ){

if( ProcessMessage() == -1 )
{
break ; // エラーが起きたらループを抜ける
}

if( Key[KEY_INPUT_SPACE]==1 ){

StopMusic() ;


}

~~~~~~~~~~~~略~~~~~~~~~~~~






スペースキーを押すと停止するようにしたいのですがどうしたらいいですか?

Re:選択画面

Posted: 2010年3月14日(日) 14:28
by kazuoni
恐らく本家の関数CheckMusicのサンプルプログラムをそのままコピぺしたようですが、
理解していますか?
メインとなるwhileループのなかにwhileループが存在し、
例外が発生しないために音が止まるまでループしているようです。

if( y == 100  && Key[KEY_INPUT_RETURN]==1 )
    PlayMusic( "1.mp3" , DX_PLAYTYPE_BACK );
else if(Key[KEY_INPUT_SPACE]==1 && CheckMusic() == 1)
    StopMusic();
のみでとりあえず大丈夫です。

Re:選択画面

Posted: 2010年3月14日(日) 16:21
by rolf
ありがとうございました!