ページ 1 / 1
4つのキーを同時に監視する
Posted: 2012年8月15日(水) 13:02
by NATTO
[1] 質問文
[1.1] Z,X,C,Aの4つのキーの状態を同時に監視できるようにして、
Zが押されたら1を、Xが押されたら2を、Cが押されたら3を、Aが押されたら4を
user_ansに格納したいです。
[1.2]
コード:
while(user_ans == 0){
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) user_ans = 1;break;
if( CheckHitKey( KEY_INPUT_X ) == 1 ) user_ans = 2;break;
if( CheckHitKey( KEY_INPUT_C ) == 1 ) user_ans = 3;break;
if( CheckHitKey( KEY_INPUT_A ) == 1 ) user_ans = 4;break;
}
[1.3]Zキーが押されたときのみしか反応しません。
[1.4] どうすればちゃんと、キーに応じて格納されるのかがわかりません。
[2] 環境
[2.1] OS : Windows7
[2.2] コンパイラ名 : VC++ 2008EE
[3] その他
・GetHitKeyStateAllを使ってもいいと思うのですが、いまいち使い方がわかりません。
・DXLib使用
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 13:29
by softya(ソフト屋)
気になる点は、user_ansが0以外になったら二度と更新されません。
あと、無限ループなのでDXライブラリ的に非常にマズイです。
GetHitKeyStateAllに関してはDXライブラリのリファレンス並びにゲームプログラミングの館に沢山例があると思います。
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 13:30
by non
コード:
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) user_ans = 1;break;
は
コード:
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) {user_ans = 1;break;}
にしないと拙いとは思うけど、whileでループさせるのもどうかな?
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 13:33
by softya(ソフト屋)
Zしか反応しないのはbreak;のせいですね。
こう書いているのと同じです。
コード:
while(user_ans == 0){
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) user_ans = 1;
break;
if( CheckHitKey( KEY_INPUT_X ) == 1 ) user_ans = 2;
break;
if( CheckHitKey( KEY_INPUT_C ) == 1 ) user_ans = 3;
break;
if( CheckHitKey( KEY_INPUT_A ) == 1 ) user_ans = 4;
break;
}
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 15:07
by NATTO
コード:
void MyMain(){
DrawBox( 0,0,640,480,GetColor(255,255,255),TRUE);
//DrawGraph(0,0, medaka1, FALSE);
SetFontSize(32);
ChangeFont("MS Pゴシック");
DrawFormatString(70,170,GetColor(255,0,0),"(Z)物語系 全1問");
DrawFormatString(70,210,GetColor(255,255,0),"(X)人物系 全1問");
DrawFormatString(70,250,GetColor(0,255,0),"(C)スキル系 全1問");
DrawFormatString(70,290,GetColor(0,0,255),"(A)物語(難問)系 全1問");
SetFontSize(40);
DrawFormatString(70,370,GetColor(0,0,0),"ジャンルを選ぶがよい!");
SetFontSize(48);
DrawFormatString(100,50,GetColor(0,0,0),"めだかボックス問題集");
DrawFormatString(100,100,GetColor(0,0,0),"~Quiz Of Medaka~");
SetFontSize(24);
/*int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
if( key & PAD_INPUT_A ) g_janru = 1;
if( key & PAD_INPUT_B ) g_janru = 2;
if( key & PAD_INPUT_C ) g_janru = 3;
if( key & PAD_INPUT_X ) g_janru = 4;*/
while(1){
ProcessMessage();
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) g_janru = 1;
if( CheckHitKey( KEY_INPUT_X ) == 1 ) g_janru = 2;
if( CheckHitKey( KEY_INPUT_C ) == 1 ) g_janru = 3;
if( CheckHitKey( KEY_INPUT_A ) == 1 ) g_janru = 4;
if( g_janru != 0) break;
}
・
・
・
というコードに変えたのですが、
最初のDrawBoxやDrawFormatString関数が実行されず、
画面が黒いままです。
GetJoypadInputState関数のほうを使えばちゃんと反応するのですが…
そっちだとずっとキーを監視してしまうみたいなので…
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 15:13
by softya(ソフト屋)
「補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html
の条件に当てはまるので基本的にダメだと思います。
MyMain()がどうやって呼び出されているかもよくわかりませんので呼び出し元も書いてください。
whileループは不要では? → 何のためのループか説明をお願いします。
[補足]
もしかしてZXCAの何れかが押されるまで待ちたいだけでしょうか?
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 15:36
by NATTO
解説書についていたcppファイルの一部分です。
コード:
// プログラムの開始関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
if (strcmp(lpCmdLine, "-f") != 0) ChangeWindowMode(TRUE);
//DXライブラリの初期化処理
if( DxLib_Init() == -1 ) return -1;
//描画対象を裏画面に設定
SetDrawScreen(DX_SCREEN_BACK);
//ファイルの読み込み
if( LoadFiles() == -1 ) return -1;
//画面サイズ(当たり判定用)の初期化
Rect2D gf = { {-64,-64}, {640+64,480+64}, 768, 608};
memcpy( &g_framerect, &gf, sizeof(Rect2D) );
//スクロール開始点の初期化
g_current_field_pos.x = 0;
g_current_field_pos.y = 0;
//ステージサイズの初期化
Rect2D gs = { {0,0}, {639,479}, 640,480} ;
memcpy( &g_stagesize, &gs, sizeof(Rect2D) );
//メインループ
g_lasttime = GetNowCount() & INT_MAX;
while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
ClsDrawScreen(); //画面を消去
MyMain();
ScreenFlip(); //画面を切り替え
//1ループにかかった時間を計測
int curtime = GetNowCount() & INT_MAX;
g_frametime = (float)(curtime - g_lasttime) / 1000.0f;
g_lasttime = curtime;
if (g_frametime > 0.03f) g_frametime = 0.03f;
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
ZXCAの4つのキーのどれかが1つ押されるまで待って、
Zなら1、Xなら2、Cなら3、Aなら4をg_janruにいれたいです。
while文でないと、次の処理にいくのではないのですか?
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 15:50
by softya(ソフト屋)
NATTO さんが書きました:解説書についていたcppファイルの一部分です。
その本だけでなく、このサイトの「ゲームプログラミングの館」もぜひお読みくださいね。
http://dixq.net/g/
NATTO さんが書きました:
ZXCAの4つのキーのどれかが1つ押されるまで待って、
Zなら1、Xなら2、Cなら3、Aなら4をg_janruにいれたいです。
while文でないと、次の処理にいくのではないのですか?
DXライブラリでは、キーを更新するため、画面を更新するため、何よりOSの仕様によりwhileで長時間留まることは許されませんので必ずメインループに戻ってください。
こういうアドベンチャーやクイズなど選択するゲームでは、状態フラグ・スイッチを使います。まぁ変数なんですけどね。
g_janruがスイッチに使えるので、g_janruが0以外になったら次の処理を呼び出すようにすべきでしょう。
それでwhile文も不要です。
つまり、こうなります。
コード:
void MyMain(){
if( g_janru == 0 ) {
DrawBox( 0,0,640,480,GetColor(255,255,255),TRUE);
//DrawGraph(0,0, medaka1, FALSE);
SetFontSize(32);
ChangeFont("MS Pゴシック");
DrawFormatString(70,170,GetColor(255,0,0),"(Z)物語系 全1問");
DrawFormatString(70,210,GetColor(255,255,0),"(X)人物系 全1問");
DrawFormatString(70,250,GetColor(0,255,0),"(C)スキル系 全1問");
DrawFormatString(70,290,GetColor(0,0,255),"(A)物語(難問)系 全1問");
SetFontSize(40);
DrawFormatString(70,370,GetColor(0,0,0),"ジャンルを選ぶがよい!");
SetFontSize(48);
DrawFormatString(100,50,GetColor(0,0,0),"めだかボックス問題集");
DrawFormatString(100,100,GetColor(0,0,0),"~Quiz Of Medaka~");
SetFontSize(24);
if( CheckHitKey( KEY_INPUT_Z ) == 1 ) g_janru = 1;
if( CheckHitKey( KEY_INPUT_X ) == 1 ) g_janru = 2;
if( CheckHitKey( KEY_INPUT_C ) == 1 ) g_janru = 3;
if( CheckHitKey( KEY_INPUT_A ) == 1 ) g_janru = 4;
} else {
・
・
・
}
いくつも問題あるなら問題番号変数でswitch分けしないとマズイですけどね。
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 16:26
by NATTO
ありがとうございます!
一応ページもみたのですが…
先ほどはどの項目をみたらよかったのですか?
どの項目を応用したら動作するかわからなかったので…
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 16:35
by softya(ソフト屋)
NATTO さんが書きました:ありがとうございます!
一応ページもみたのですが…
先ほどはどの項目をみたらよかったのですか?
どの項目を応用したら動作するかわからなかったので…
ひと通りのイメージは頭に入っていないと似たパターンの時に応用できないと思います。
これは、暗記じゃないですよ。処理パターンのイメージだけ頭の中にあれば良いです。
まぁ見ずに書けるのが理想ですが。
ただ、少なくとも「補足資料.11章 書いてはいけない4つの処理」には違反しようとしてたので全体に目を通していなかった事は確かですよね?
今回の件で似ているものなら「旧ゲームプログラミングの館」の
34. main関数の書き方。
http://dixq.net/g/37.html
でしょうか。
大分違って見えるでしょうが、根本的な思想は同じです。
【補足】
こういうクイズ問題は、プログラム書いていくとメンテが大変なので普通はテキストファイルにします。
座標とか、文字とか、表示するグラフィックの番号とかをテキストに書いておくんです。
Re: 4つのキーを同時に監視する
Posted: 2012年8月15日(水) 17:00
by NATTO
本当ですね…
これからは隅から隅まで見るようにしていきたいと思います。
確かに、似ているところがありましたね。