ページ 11

順番に表示したのですが

Posted: 2009年6月01日(月) 04:27
by cc
下のプログラムを改良してエンターを押すごとに
A→AB→ABC→ABCD
という風に順番に表示させたい。
しかし、下のままだと、ABCDというように、1回押すだけで一気に表示されてしまいます。
どうすればよいでしょうか?
#include "DxLib.h"
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
  ChangeWindowMode(TRUE);
  if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;
 
  int col1 = GetColor(255, 255, 255);
  char input[4];
  int i = 0;
  
  while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
   if(CheckHitKey(KEY_INPUT_RETURN)){
     switch(i){
       case 0:
         input = 'A';
	 break;
       case 1:
         input = 'B';
	 break;
       case 2:
         input = 'C';
	 break;
       case 3:
         input = 'D';
	 break;
    }
    i++;
  }
  if(CheckHitKey(KEY_INPUT_SPACE)){
    ClearDrawScreen();
    DrawString(0, 0, input, col1);
  }
     
 
    ScreenFlip();
  }
 
    DxLib_End();
    return 0;
}

Re:順番に表示したのですが

Posted: 2009年6月01日(月) 06:15
by MNS
たぶん、エンターキーを押して、すぐ離したとしても、
4回以上はエンターキーが押されたことになってしまってるんだと思います。
適当にインターバルをつけると良いと思います。
int interval = 0;

if(CheckHitKey(KEY_INPUT_RETURN) && interval % 10 == 0)

++interval;
など。

Re:順番に表示したのですが

Posted: 2009年6月01日(月) 08:23
by Dixq (管理人)
ゲームの館にどれ位キー入力があったか調べる方法が書いてあるのでよければ参考にしてください。

Re:順番に表示したのですが

Posted: 2009年6月01日(月) 13:00
by kazuoni
CheckHitKey()はキー入力があれば1、なければ0なんで、
MNSさんもおっしゃっていますが、
ループはものすごく速いので、
一回押したつもりでも、プログラムは数十ループぐらいしてます。
(ウェイト機能がなければ)

http://dixq.net/g/#40のキー監査を使うと
キー監査用配列をKey[256]とすると、

if(Key[KEY_INPUT_RETURN]==1)

なんて使えて便利ですよ。

Re:順番に表示したのですが

Posted: 2009年6月02日(火) 06:29
by cc
GetHitKeyStateAll_2を使ったらうまくいきました。
ありがとうございました。

上のプログラムとはまた別の話になってしまうのですが、GetHitKeyStateAll_2の使い方についてです。
int Key[256];

while(GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
  if(Key[KEY_INPUT_RIGHT]==1) state = 1;
  if(Key[KEY_INPUT_RETURN]==1) state = 2;
  if(Key[KEY_INPUT_SPACE]==1) state = 3;
}

switch(state){
  case 1:
    .......
  case 2:
    .......
  case 3:
    .......
}
caseのところは省略

上のようなプログラムを作ろうとしているんですが、キーが押されてもなにも処理が行われませんでした。
CheckHitKeyを用いてやってみたらうまくいきました。
GetHitKeyStateAll_2の使い方が間違っていると思うのですが、どこが間違っているのかわかりません。
ご指摘願います。

Re:順番に表示したのですが

Posted: 2009年6月02日(火) 15:35
by kazuoni
上の記述だと、キーを押しても、
エスケープが押されるまでは永遠とループしているからではないですか?

Re:順番に表示したのですが

Posted: 2009年6月02日(火) 22:41
by cc
while(GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0)
の部分を
if(GetHitKeyStateAll_2(Key)==0)
としたらうまくいったみたいなんですが、どうでしょうか?

Re:順番に表示したのですが

Posted: 2009年6月02日(火) 22:46
by kazuoni
&&=ANDですので、
GetHitKeyStateAll_2(Key)==0
かつ
Key[KEY_INPUT_ESCAPE]==0
のとき、ループするって意味です。

GetHitKeyStateAll_2の役割によって、エスケープが押されていなければ、
Key[KEY_INPUT_ESCAPE]は常にゼロです。
なので何も起こらなかった
(正確には、永遠とループしていた)
ということが起きていました。

#どんな処理を採用したか分からないですけど、
#GetHitKeyStateAll_2の戻り値は常に0ですので^^;

Re:順番に表示したのですが

Posted: 2009年6月02日(火) 23:06
by cc
すいません。
具体的にどうすればよいのでしょう。
自分には難しすぎて・・・
すみません。

Re:順番に表示したのですが

Posted: 2009年6月03日(水) 00:14
by kazuoni
もう一度基礎をしっかり復習したほうがいいかもしれませんね。。
以下の挙げる者が分かれば、今回のことは理解できるはずです。
・各演算子のもつ性質
・各条件分岐のフローチャート
・関数(の戻り値)

これらは今後プログラムを組む時には必ず出てきます。
(まだまだたくさんありますが・・・)
急がば回れって事ですかね^^;

ちょっと困っていそうな所を想像で考えてみます^^;
GetHitKeyStateAll_2の置き場っと勝手に判断します。
おそらく、ccさんは管理人さんのゲームプログラミングの館を見てきたんだと思います。
その時に、なんとなくかいつまんでコピペしていたら、
while文の中にキー監査があるから、
これを見習って・・・て感じかもしれないです。
whileの条件にキー監査を記述する理由は(恐らくですが)
「ゲームループ毎に必ず呼び出す関数」
と明示したかったからこの形をしているんだと思います。
なので、GetHitKeyStateAll_2の置く場所はループ毎に必ず通るところなら
どこに記述してもよいです。
ただ、見やすさとしては、管理人さんのサンプルが見やすいとは思いますが。

今回のプログラムのサンプル作ってみましたので、参考にしてみてください。

#話がずれたかも・・・しれないです。勝手に想像しなければよかったorz

Re:順番に表示したのですが

Posted: 2009年6月03日(水) 00:52
by cc
kazuoniさんの想像通りです。
管理人のプログラムを参考にして作りました。
kazuoniさんにご指摘いただいた3つのことをしっかり復習したいと思います。
本当に丁寧に教えていただいてありがとうございました。