windowsXP
vusual C++ 2008
DXライブラリを使用しています。
はじめまして、プログラミング初心者のkuriです。
以下のプログラムを実行してみた結果、予想していた動きをせず色々と考えてみたのですが
解らなかったため質問させて頂きました。
プログラム内容はEnter入力があった場合、乱数を取得して
その乱数に対した文字を表示するという単純なものです。
質問①"Enterを押してください"と表示されている状態で、
Enterを2回押下しないと32行目からの表示をしてくれません。
(私の予想していた結果では一度の押下でOKのはず・・・)
質問②WaitKey();でEnter以外を押下した場合は"Enterを押してください"と再表示されるのですが、
Enterを押下した場合、すぐに32行目からの表示をしてしまいます。
ためしにデバッグで変数Key[28]に値を1入れてステップインして行った場合、ループ処理の
GetHitKeyStateAll( Key )でKey[28]の値は0にしっかりと戻っていました。
(私の予想していた結果ではEnter押下でも"Enterを押してください"と再表示されるはず・・・)
以上が私の疑問と質問です。初歩的な質問かと思いますがよろしくお願いいたします。
/************************************************************************************************
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
/*変数宣言*/
char Key[256]; //キー入力取得
int rand; //乱数取得
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
//↑ウィンドウ化 //↑初期化処理
/*変数初期化*/
rand = 0;
memset( Key,'\0',sizeof(Key) );
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
while( !ProcessMessage() && !ClearDrawScreen()
&& !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] ) {
if( Key[KEY_INPUT_RETURN ] == 0 ) { //エンターが入力されていない場合
DrawString( 640/3,480/2,"Enterを押してください",GetColor( 255 , 255 , 255 ) );//表示
} else if( Key[KEY_INPUT_RETURN ] == 1 ) { //エンターが入力された場合
ClearDrawScreen(); //画面をクリア
rand=GetRand(2); //乱数取得
if( rand == 0 ) { //取得した乱数か0の場合
DrawString( 640/2,480/2,"赤",GetColor( 255 , 0 , 0 ) );//画面に表示
} else if( rand==1 ) { //取得した乱数か1の場合
DrawString( 640/2,480/2,"青",GetColor( 0 , 0 , 255 ) );//画面に表示
} else if( rand==2 ) { //取得した乱数か2の場合
DrawString( 640/2,480/2,"緑",GetColor( 0 , 255 , 0 ) );//画面に表示
}
WaitKey(); //キー入力待ち
}
ScreenFlip();//裏画面を表画面に反映
}
DxLib_End();
return 0;
}
************************************************************************************************/
GetHitKeyStateAll関数を使った処理が上手くいきません
Re:GetHitKeyStateAll関数を使った処理が上手くいきません
追記
*このプログラムは質問を読まずに書いてましたのでスルー推奨w
*質問読んだ後に書いたのは次の私のレスにあります。
while( !ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll_2( Key ) && !Key[KEY_INPUT_ESCAPE] ) {
if( Key[KEY_INPUT_RETURN ] == 0 ) { //エンターが入力されていない場合
DrawString( 640/3,480/2,"Enterを押してください",GetColor( 255 , 255 , 255 ) );//表示
} else if( Key[KEY_INPUT_RETURN ] == 1 ) { //エンターが入力された場合
rand=GetRand(2); //乱数取得
}
if( Key[KEY_INPUT_RETURN ] >= 1 ) {
if( rand == 0 ) { //取得した乱数か0の場合
DrawString( 640/2,480/2,"赤",GetColor( 255 , 0 , 0 ) );//画面に表示
} else if( rand==1 ) { //取得した乱数か1の場合
DrawString( 640/2,480/2,"青",GetColor( 0 , 0 , 255 ) );//画面に表示
} else if( rand==2 ) { //取得した乱数か2の場合
DrawString( 640/2,480/2,"緑",GetColor( 0 , 255 , 0 ) );//画面に表示
}
}
ScreenFlip();//裏画面を表画面に反映
}
*あと、読みにくかったのでインデントは正しくおこないましょう。
追記
GetHitKeyStateAll_2 関数については
http://dixq.net/g/41.html
こちらを参照してみてください。
*このプログラムは質問を読まずに書いてましたのでスルー推奨w
*質問読んだ後に書いたのは次の私のレスにあります。
while( !ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll_2( Key ) && !Key[KEY_INPUT_ESCAPE] ) {
if( Key[KEY_INPUT_RETURN ] == 0 ) { //エンターが入力されていない場合
DrawString( 640/3,480/2,"Enterを押してください",GetColor( 255 , 255 , 255 ) );//表示
} else if( Key[KEY_INPUT_RETURN ] == 1 ) { //エンターが入力された場合
rand=GetRand(2); //乱数取得
}
if( Key[KEY_INPUT_RETURN ] >= 1 ) {
if( rand == 0 ) { //取得した乱数か0の場合
DrawString( 640/2,480/2,"赤",GetColor( 255 , 0 , 0 ) );//画面に表示
} else if( rand==1 ) { //取得した乱数か1の場合
DrawString( 640/2,480/2,"青",GetColor( 0 , 0 , 255 ) );//画面に表示
} else if( rand==2 ) { //取得した乱数か2の場合
DrawString( 640/2,480/2,"緑",GetColor( 0 , 255 , 0 ) );//画面に表示
}
}
ScreenFlip();//裏画面を表画面に反映
}
*あと、読みにくかったのでインデントは正しくおこないましょう。
追記
GetHitKeyStateAll_2 関数については
http://dixq.net/g/41.html
こちらを参照してみてください。

Re:GetHitKeyStateAll関数を使った処理が上手くいきません
失礼、ちゃんと質問読んでいませんでした。
質問に忠実に答えるとこんなプログラムになるとおもいます。
while( !ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] ) {
if( Key[KEY_INPUT_RETURN ] == 0 ) { //エンターが入力されていない場合
DrawString( 640/3,480/2,"Enterを押してください",GetColor( 255 , 255 , 255 ) );//表示
} else if( Key[KEY_INPUT_RETURN ] == 1 ) { //エンターが入力された場合
rand=GetRand(2); //乱数取得
if( rand == 0 ) { //取得した乱数か0の場合
DrawString( 640/2,480/2,"赤",GetColor( 255 , 0 , 0 ) );//画面に表示
} else if( rand==1 ) { //取得した乱数か1の場合
DrawString( 640/2,480/2,"青",GetColor( 0 , 0 , 255 ) );//画面に表示
} else if( rand==2 ) { //取得した乱数か2の場合
DrawString( 640/2,480/2,"緑",GetColor( 0 , 255 , 0 ) );//画面に表示
}
ScreenFlip();//質問①の原因
WaitKey();
do{
GetHitKeyStateAll( Key );
}while(Key[KEY_INPUT_RETURN ] == 1);//質問②の回避方法
}
ScreenFlip();//裏画面を表画面に反映
}
*追記
質問②の回避方法
とありましたが、これは非推奨です。
ProcessMessage() がEnterキーを押している間、ずっと呼ばれないためです。
それを回避するために、do while ループ内で、この関数を呼ぶのも非推奨です。
これはプログラムを複雑化し、メインループ一周にかかる時間を大きく変動してしまうためです。
バグにつながる時もあります。
ともかく、推奨な解決方法は、私の一番最初のレスのサンプルにあった、 GetHitKeyStateAll_2 関数の使用です。
この関数は、キーをどれだけの間押していたか記録してくれます。
(*注:この関数はソースコードに書き込む必要があります。)
質問に忠実に答えるとこんなプログラムになるとおもいます。
while( !ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] ) {
if( Key[KEY_INPUT_RETURN ] == 0 ) { //エンターが入力されていない場合
DrawString( 640/3,480/2,"Enterを押してください",GetColor( 255 , 255 , 255 ) );//表示
} else if( Key[KEY_INPUT_RETURN ] == 1 ) { //エンターが入力された場合
rand=GetRand(2); //乱数取得
if( rand == 0 ) { //取得した乱数か0の場合
DrawString( 640/2,480/2,"赤",GetColor( 255 , 0 , 0 ) );//画面に表示
} else if( rand==1 ) { //取得した乱数か1の場合
DrawString( 640/2,480/2,"青",GetColor( 0 , 0 , 255 ) );//画面に表示
} else if( rand==2 ) { //取得した乱数か2の場合
DrawString( 640/2,480/2,"緑",GetColor( 0 , 255 , 0 ) );//画面に表示
}
ScreenFlip();//質問①の原因
WaitKey();
do{
GetHitKeyStateAll( Key );
}while(Key[KEY_INPUT_RETURN ] == 1);//質問②の回避方法
}
ScreenFlip();//裏画面を表画面に反映
}
*追記
質問②の回避方法
とありましたが、これは非推奨です。
ProcessMessage() がEnterキーを押している間、ずっと呼ばれないためです。
それを回避するために、do while ループ内で、この関数を呼ぶのも非推奨です。
これはプログラムを複雑化し、メインループ一周にかかる時間を大きく変動してしまうためです。
バグにつながる時もあります。
ともかく、推奨な解決方法は、私の一番最初のレスのサンプルにあった、 GetHitKeyStateAll_2 関数の使用です。
この関数は、キーをどれだけの間押していたか記録してくれます。
(*注:この関数はソースコードに書き込む必要があります。)
