4つのキーを同時に監視する

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

4つのキーを同時に監視する

#1

投稿記事 by NATTO » 13年前

[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使用

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

Re: 4つのキーを同時に監視する

#2

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

気になる点は、user_ansが0以外になったら二度と更新されません。
あと、無限ループなのでDXライブラリ的に非常にマズイです。

GetHitKeyStateAllに関してはDXライブラリのリファレンス並びにゲームプログラミングの館に沢山例があると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 15年前

Re: 4つのキーを同時に監視する

#3

投稿記事 by non » 13年前

コード:

if( CheckHitKey( KEY_INPUT_Z ) == 1 ) user_ans = 1;break;

コード:

if( CheckHitKey( KEY_INPUT_Z ) == 1 ) {user_ans = 1;break;}
にしないと拙いとは思うけど、whileでループさせるのもどうかな?
non

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

Re: 4つのキーを同時に監視する

#4

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

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;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

NATTO

Re: 4つのキーを同時に監視する

#5

投稿記事 by NATTO » 13年前

コード:

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関数のほうを使えばちゃんと反応するのですが…
そっちだとずっとキーを監視してしまうみたいなので…

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

Re: 4つのキーを同時に監視する

#6

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

「補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html
の条件に当てはまるので基本的にダメだと思います。

MyMain()がどうやって呼び出されているかもよくわかりませんので呼び出し元も書いてください。
whileループは不要では? → 何のためのループか説明をお願いします。

[補足]
もしかしてZXCAの何れかが押されるまで待ちたいだけでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

NATTO

Re: 4つのキーを同時に監視する

#7

投稿記事 by NATTO » 13年前

解説書についていた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文でないと、次の処理にいくのではないのですか?

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

Re: 4つのキーを同時に監視する

#8

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

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分けしないとマズイですけどね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

NATTO

Re: 4つのキーを同時に監視する

#9

投稿記事 by NATTO » 13年前

ありがとうございます!
一応ページもみたのですが…
先ほどはどの項目をみたらよかったのですか?
どの項目を応用したら動作するかわからなかったので…

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

Re: 4つのキーを同時に監視する

#10

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

NATTO さんが書きました:ありがとうございます!
一応ページもみたのですが…
先ほどはどの項目をみたらよかったのですか?
どの項目を応用したら動作するかわからなかったので…
ひと通りのイメージは頭に入っていないと似たパターンの時に応用できないと思います。
これは、暗記じゃないですよ。処理パターンのイメージだけ頭の中にあれば良いです。
まぁ見ずに書けるのが理想ですが。

ただ、少なくとも「補足資料.11章 書いてはいけない4つの処理」には違反しようとしてたので全体に目を通していなかった事は確かですよね?

今回の件で似ているものなら「旧ゲームプログラミングの館」の
34. main関数の書き方。
http://dixq.net/g/37.html
でしょうか。
大分違って見えるでしょうが、根本的な思想は同じです。

【補足】
こういうクイズ問題は、プログラム書いていくとメンテが大変なので普通はテキストファイルにします。
座標とか、文字とか、表示するグラフィックの番号とかをテキストに書いておくんです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

NATTO

Re: 4つのキーを同時に監視する

#11

投稿記事 by NATTO » 13年前

本当ですね…
これからは隅から隅まで見るようにしていきたいと思います。
確かに、似ているところがありましたね。

閉鎖

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