ページ 11

40a. について、2つ質問です

Posted: 2010年4月23日(金) 20:14
by てとら
はじめまして、最近プログラミングに手を出し始めました、てとらと申します。
初歩的な質問なのですが、40a. キーがどれ位押されたかを監視する関数で

 int GetHitKeyStateAll_2( int *KeyStateBuf ) ;

という関数が作成されていますが、この関数はどこで呼び出されているのでしょうか?

また、

 int Key[256];
 を用意して、エンターを押し続けた状態で
 GetHitKeyStateAll_2(Key);
 を100回呼べばその時
 Key[KEY_INPUT_RETURN]は100が入っています。

とありますが、この100が格納される

 Key[KEY_INPUT_RETURN]

というのは、一体どんな変数なのですか?(変数かどうかも分からないのですが…)

よろしければ、どなたか教えて下さい!

Re:40a. について、2つ質問です

Posted: 2010年4月23日(金) 23:21
by ookami
ここですよね?
http://dixq.net/g/41.html

てとらさんのレベルが分からないので直球で回答いたします。

> この関数はどこで呼び出されているのでしょうか?
一番下のサンプルの while の条件文の中に見えますね。

> Key[KEY_INPUT_RETURN] というのは、一体どんな変数なのですか?
int Key[256]; の KEY_INPUT_RETURN 番目の要素ですね。int型の変数です。

僭越ながら、40a.までは理解されていますか?

Re:40a. について、2つ質問です

Posted: 2010年4月24日(土) 03:39
by てとら
>ookamiさん
すみません、自分のレベルを書き忘れました。
一応40a.までは何とか理解しており、それと平行してC++の教本を読み解いています
(現在ポインタで苦戦していますが…)。

>while の条件文の中

 ↑入力状態を保存

のところですね。頭から抜けていました、ありがとうございます。


> Key[KEY_INPUT_RETURN]
質問で返してしまい申し訳ないのですが、なぜ

 GetHitKeyStateAll_2(Key);
 を100回呼べばその時
 Key[KEY_INPUT_RETURN]は100が入っています。

ということになるのでしょうか?
個人の考えとしては、

①char GetHitKeyStateAll_Key[256];
 char型のGetHitKeyStateAll_Ketという変数配列を作成。

②GetHitKeyStateAll( GetHitKeyStateAll_Key );
 ①で作ったGetHitKeyStateAll_Keyに、キーボードが押されているか?の判定を取得。

③for(int i=0;i<256;i++){
 変数iが256より小さい時、

④if(GetHitKeyStateAll_Key==1) KeyStateBuf++;
 もし、GetHitKeyStateAll_Keyが押されていたら、KeyStateBuf配列の中身をインクリメント。
 (以下押されている間繰り返し)

⑤else KeyStateBuf=0;
 それ以外(キーが放されるなど)で、KeyStateBuf配列の中身を0に。

⑥GetHitKeyStateAll_2(Key)==0
 While文の条件式にある関数呼び出しで、int KeyStateBuf[/url]に、int Key[256]を実引数として渡す。

⑦関数呼び出し

⑧if(GetHitKeyStateAll_Key==1) KeyStateBuf++;
 これにより、int Key(この場合、iはエンターキー)に格納されている値をインクリメント
 (以下押されている間繰り返し)

長くなってしまいましたが、こういうことで良いのでしょうか?
結局関数内部についての質問になってしまいましたが、どうにも頭がこんがらがってしまいまして…

よろしければ、どなたか教えて下さい。お願いします!

Re:40a. について、2つ質問です

Posted: 2010年4月24日(土) 09:04
by ひよこ
GetHitKeyStateAll_2(Key);はKey配列にキーの押されているカウンタを+1します。
押されてなかったら0にします。
押された状態で100回呼ばれると100になります。

Re:40a. について、2つ質問です

Posted: 2010年4月24日(土) 09:05
by ookami
①~⑧、それぞれ「C++言語 → 日本語」の直訳と言う意味では合っています。

補足になるかわかりませんが...

dxlib.h とdxdirectx.h を見ると、
#define KEY_INPUT_RETURN D_DIK_RETURN // エンターキー
#define D_DIK_RETURN (0x1C)

となっています。つまり、


Key[KEY_INPUT_RETURN]

は、

Key[28]

と展開されます。(1Cを10進数にすると28)

> ③for(int i=0;i<256;i++){

の i が 28 の時、Enterキーが押されていれば(GetHitKeyStateAll_Key[28]==1なら) KeyStateBuf[28] が +1(Key[28]が+1) されます。従って、100回繰り返せば Key[28] は 100 になっています。

---

はずかしながら「実引数」って知りませんでした^^; 勉強になりました;

Re:40a. について、2つ質問です

Posted: 2010年4月24日(土) 10:40
by Dixq (管理人)
GetHitKeyStateAllっていう関数は既にDXライブラリにあります。
しかしこの関数では特定のキーが「押されているか」「押されていないか」しか解らないので、「どれ位押されているか」が解らず、困る場合が多いのです。

例えば「タメ撃ち」であったり、メニュー項目の遷移時の入力であったり。
メニュー項目の遷移はキーが押された瞬間のみ行いたいですよね。

詳しく言えば
「下キーが押されている間、選択状態を下に移動」ってプログラムを書いてしまうと
1秒間下キーを押しっぱなしだと選択項目が60個下に動いてしまいます。
しかし一度下キーを押したら一つだけ下に動かしたいはずです。

こんな風に「どれ位押したか」を判定できるように拡張したのが GetHitKeyStateAll_2関数です。
キーボードの入力状態は256種類にわけて GetHitKeyStateAll関数によって配列に0か1で格納されます。

その引数はchar型ですから、そのままの状態で入力した長さを加算出来ません。
char型はunsignedでも255ですから、4秒しかカウント出来ません。
そこで、int型で入力状態を表します。

まずは今の瞬間キーが押されてるかどうかを01であらわされるchar型変数に格納し、
256種類あるキーの入力状態を、256個の配列要素を持つint型に対応させて計算します。

キーが押されているなら要素の値を加算、押されていないなら0を格納します。

この計算をする関数を1秒間に60回呼べば、1秒間押しっぱなしならそのキーの入力状態は60になります。
こうすることで、どれ位キーが入力したかがわかり便利なのです。

Re:40a. について、2つ質問です

Posted: 2010年4月24日(土) 22:22
by てとら
>ひよこさん、ookamiさん、管理人様
ありがとうございます、おかげで理解する事ができました!
引き続き勉強させていただこうと思います。