合計 昨日 今日

キーボード入力について。

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: かるた
[URL]
Date: 2017年4月21日(金) 17:35
No: 1
(OFFLINE)

 キーボード入力について。

 昨日からお世話になっております。かるたと申します。
 簡単な脳トレゲームが作りたくて奮闘しております。
今日は、ランダムな計算問題を作って、計算問題を表示した後、それに対してキーボード入力で答えを入力し、
〇か×を出力するプログラムを作っておりました。
 ところが、計算問題を表示した後、すぐに〇が表示されてしまいます。
例えば、プレイヤーがキーボードで「0」と入力することを考えた場合、switch文でcase0として
コード[C++]: 全て選択
1
2
3
4
5
6
7
switch("問題の答え"){
if (KEY_INPUT_0)
 
                    DrawFormatString(200, 300, Green, "〇 ");
                         else
                             DrawFormatString(200, 300, Green, "× ");
}

と僕は考えました。しかし、何も押さなくても〇と出力されます。
ソースコードは、
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "DxLib.h"
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int Key[256]; // キーが押されているフレーム数を格納する
 
                  // キーの入力状態を更新する
 
 
 
 
    ChangeWindowMode(TRUE);          // ウインドウモードに変更
    if (DxLib_Init() == -1) return -1; //DXライブラリ初期化 エラーが起きたら終了
    int Random[2]; //乱数の配列を二つ用意
    int Green = GetColor(0, 255, 0);
    int x;//二つの乱数を合計した数の変数を用意
    SRand(10);                          //乱数の初期値を10で設定。
    Random[0] = GetRand(5);
    Random[1] = GetRand(4);
 
 
    int StartTime;  //今の時間
    ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
 
    bool displayText = true;//計算問題の文字を表示するか
    bool displayText2 = false;//回答の文字を表示するか
 
    // 文字を表示するか
    StartTime = GetNowCount(); // プログラムの開始時刻
 
    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
 
        if (displayText)
        {
            DrawFormatString(200, 200, Green, "%d + %d = ", Random[0], Random[1]);
            if (GetNowCount() - StartTime >= 6000)
            {
                // 6秒経ったら文字を表示しなくする
                displayText = false;
 
            }
        }
 
 
        if (displayText == 0) { //乱数の足し算の表示が消えた後
            displayText2 = true;
 
            if (displayText2) {
                DrawFormatString(200, 200, Green, "計算の答えを入力しなさい。");
 
                x = Random[0] + Random[1];
                switch (x) {
 
                case 0:  if (KEY_INPUT_0)
                    DrawFormatString(200, 300, Green, "〇 ");
                         else
                             DrawFormatString(200, 300, Green, "× ");
 
                case 1:if (KEY_INPUT_1)
                    DrawFormatString(200, 200, Green, "〇");
                       else
                           DrawFormatString(200, 300, Green, "× ");
                    break;
 
                case 2:if (KEY_INPUT_2)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "× ");
                    break;
 
                case 3:if (KEY_INPUT_3)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "×");
 
                    break;
 
                case 4:if (KEY_INPUT_4)
                    DrawFormatString(200, 300, Green, "〇");
                       else
                           DrawFormatString(200, 300, Green, "×");
                    break;
 
                case 5:if (KEY_INPUT_5)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "× ");
                    break;
 
                case 6:if (KEY_INPUT_6)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "×");
                    break;
 
                case 7:if (KEY_INPUT_7)
                    DrawFormatString(200, 300, Green, "〇");
                       else
                           DrawFormatString(200, 300, Green, "× ");
                    break;
 
                case 8:if (KEY_INPUT_8)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "× ");
                    break;
 
                case 9:if (KEY_INPUT_9)
                    DrawFormatString(200, 300, Green, "〇 ");
                       else
                           DrawFormatString(200, 300, Green, "×");
                    break;
                }
                               
           
                    }
            }
 
    }
    WaitKey();
    DxLib_End();        // DXライブラリ使用の終了処理
 
    return 0;        // ソフトの終了r
 
}

です。よろしくお願いします。

Name: keito94
[URL]
プログラマー(31,510 ポイント)
Date: 2017年4月21日(金) 20:17
No: 2
(OFFLINE)

 Re: キーボード入力について。

もしかして、
コード[C++]: 全て選択
1
if(Key[入力するキー])

ではないのでしょうか?
プログラムは完全に無理だったけど、完全フリーのゲームエンジンGodotに出会ってからはボクの人生は変わった…。
Godotを試したい人は、ここで。
一応プログラムの履歴は、C言語+DXライブラリ→Python+Pygame→Godot Engine。
まあ、プログラム学ぶより、ゲームエンジンなり、ツクールなり使えば楽だということよ。
Godot広まらないかな…。(空想)

Name: かるた
[URL]
Date: 2017年4月21日(金) 21:40
No: 3
(OFFLINE)

 Re: キーボード入力について。

keito94さん回答ありがとうございます。
switch文の中身を(Key[KEY_INPUT_])に変えたのですが、〇がすぐに表示されます。
キー入力したものが合計値と一緒なら〇を出力したいのですが・・・

Name: みけCAT
[URL]
伝説なるハッカー(675,369 ポイント)
Date: 2017年4月21日(金) 22:13
No: 4
(OFFLINE)

 Re: キーボード入力について。

かるた さんが書きました:switch文の中身を(Key[KEY_INPUT_])に変えたのですが、〇がすぐに表示されます。

Keyが明示的に初期化されていない自動変数となっているので、値は不定です。
キーの状態を取得してKeyに格納する処理が必要です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: かずま
[URL]
Date: 2017年4月21日(金) 22:43
No: 5
(OFFLINE)

 Re: キーボード入力について。

次のようコードを修正してみました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    if (displayText2) {
        DrawFormatString(200, 200, Green, "計算の答えを入力しなさい。");
        static int ki[10] = {
            KEY_INPUT_0, KEY_INPUT_1, KEY_INPUT_2, KEY_INPUT_3, KEY_INPUT_4,
            KEY_INPUT_5, KEY_INPUT_6, KEY_INPUT_7, KEY_INPUT_8, KEY_INPUT_9,
        };
        char Buf[256];
        GetHitKeyStateAll(Buf);
        x = Random[0] + Random[1];
        if (Buf[ki[x]])
            DrawFormatString(200, 300, Green, "〇 ");
        else
            DrawFormatString(200, 300, Green, "× ");
    }

私の環境では、Srand(10) の下で常に 3 + 2 = が表示され、
5 のキーを押している間だけ、〇 が表示されました。
while ループは 1/60 秒ごとに実行されるので、表示は常に更新され、
キーを押すのをやめると、× の表示に変わります。

int Key[256]; が用意されていても、そこには何の値も設定されていません。
そこで、char Buf[256]; を用意し、GetHitKeyStateAll(Buf); で現在のすべての
キーの状態を取得したということです。

Name: かずま
[URL]
Date: 2017年4月22日(土) 00:19
No: 6
(OFFLINE)

 Re: キーボード入力について。

int Key[256]; があったので、全部のキーの状態を取得する GetHitKeyAll を
使ってみましたが、よく考えてみると、問題の正解に対応するキーが押されて
いるかどうかだけを見ればよいので、CheckHitKey が使えます。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
    if (displayText2) {
        DrawFormatString(200, 200, Green, "計算の答えを入力しなさい。");
        static int ki[10] = {
            KEY_INPUT_0, KEY_INPUT_1, KEY_INPUT_2, KEY_INPUT_3, KEY_INPUT_4,
            KEY_INPUT_5, KEY_INPUT_6, KEY_INPUT_7, KEY_INPUT_8, KEY_INPUT_9,
        };
        x = Random[0] + Random[1];
        if (CheckHitKey([ki[x]])
            DrawFormatString(200, 300, Green, "〇 ");
        else
            DrawFormatString(200, 300, Green, "× ");
    }

でも、本当にこんな仕様でいいのですか?
まだ解答を入力する前に × が表示されていてかまわないのですか?
プログラムを変更して、6 + 9 = なんて問題を出すようにしたいとき、
1 と 5 のキーが連続して押されるのをチェックするんですか?

Name: かるた
[URL]
Date: 2017年4月22日(土) 08:16
No: 7
(OFFLINE)

 Re: キーボード入力について。

先日からお世話になっております。かずまさん。

はい。はじめから×が出ているのは、だめです。
プレイヤーがキー入力したら〇か×が出力されるような仕様を教えていただきたいです。

後、2桁の場合もできれば教えていただけたらと思います。

本当に昨日からありがとうございます。

Name: かずま
[URL]
Date: 2017年4月22日(土) 09:09
No: 8
(OFFLINE)

 Re: キーボード入力について。

かるた さんが書きました:プレイヤーがキー入力したら〇か×が出力されるような仕様を教えていただきたいです。

仕様は、「プレイヤーがキー入力したら〇か×が出力される」ですね。
その仕様を実現するアルゴリズム(さらにはコード)を教えてほしいということですね。

displayText2 を活用しましょう。
間違ったキー入力もチェックしないといけないので、GetHitKeyStateAll を使います。

また、SRand で 10 を設定せず、毎回異なる問題が作れるようにしたり、
DxLib_Init を 2回実行するのをやめたりもしました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "DxLib.h"
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(TRUE);            // ウインドウモードに変更
    if (DxLib_Init() == -1) return -1; // DXライブラリ初期化 エラーが起きたら終了
    SetDrawScreen(DX_SCREEN_BACK);
 
    int Green = GetColor(0, 255, 0);
    bool displayText = true;       // 計算問題の文字を表示するか
    bool displayText2 = false;     // 解答の文字を表示するか
    int answer = -1;               // 入力された解答
 
    int StartTime = GetNowCount(); // プログラムの開始時刻
    SRand(StartTime);              // 乱数の初期値を設定
 
    int Random[2];                 // 乱数の配列を二つ用意
    Random[0] = GetRand(5);
    Random[1] = GetRand(4);
    int x = Random[0] + Random[1]; // 二つの乱数を合計した数
 
    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
        if (displayText) {
            DrawFormatString(200, 200, Green, "%d + %d =", Random[0], Random[1]);
            if (GetNowCount() - StartTime >= 6000) {
                displayText = false; // 6秒経ったら文字を表示しなくする
            }
        }
        else { // 乱数の足し算の表示が消えた後
            DrawFormatString(200, 200, Green, "計算の答えを入力しなさい。");
            static int ki[10] = {
                KEY_INPUT_0, KEY_INPUT_1, KEY_INPUT_2, KEY_INPUT_3, KEY_INPUT_4,
                KEY_INPUT_5, KEY_INPUT_6, KEY_INPUT_7, KEY_INPUT_8, KEY_INPUT_9,
            };
            char Buf[256];
            GetHitKeyStateAll(Buf);
            for (int i = 0; i < 10; i++) {
                if (Buf[ki[i]]) {
                    displayText2 = true;
                    answer = i;
                    break;
                }
            }
            if (displayText2) {
                DrawFormatString(200, 250, Green, "%d", answer);
                if (answer == x)
                    DrawFormatString(200, 300, Green, "〇 ");
                else
                    DrawFormatString(200, 300, Green, "× ");
            }
        }
    }
 
    DxLib_End();     // DXライブラリ使用の終了処理
    return 0;        // ソフトの終了r
}

Name: かるた
[URL]
Date: 2017年4月22日(土) 10:01
No: 9
(OFFLINE)

 Re: キーボード入力について。

ありがとうございます。かずまさん。僕が望んでいた仕様です。それに読みやすい!!
ただ、自分初心者なので、分からない箇所があります。
コード[C++]: 全て選択
1
2
3
4
5
6
static int ki[10] = {
                KEY_INPUT_0, KEY_INPUT_1, KEY_INPUT_2, KEY_INPUT_3, KEY_INPUT_4,
                KEY_INPUT_5, KEY_INPUT_6, KEY_INPUT_7, KEY_INPUT_8, KEY_INPUT_9,
            };
            char Buf[256];
            GetHitKeyStateAll(Buf);

のところを詳しく教えていただけたら幸いです。
僕は、c言語のIf文、for文、配列を理解しているレベルの知識しかありません。

Name: かずま
[URL]
Date: 2017年4月22日(土) 14:33
No: 10
(OFFLINE)

 Re: キーボード入力について。

かるた さんが書きました:c言語のIf文、for文、配列を理解しているレベルの知識しかありません。

bool、true、false というキーワードを使っているということは、
使用している言語は、C ではなく、C++ です。

配列は、理解しているんですよね。
宣言時に、= { ... } で初期化できるのが解らないのですか?

関数やブロックの中で変数を宣言すると、自動変数になり、
そこを通るたびに毎回初期化が実行されます。

static を付けると、静的変数となり、初期化は 1回だけになります。
というより、この場合、コンパイル時に初期値が割り当てられていて、
初期化の実行はないでしょう。

DxLib のリファレンスマニュアルをよく読みましょう。
GetHitKeyStateAllに詳しく解説されています。

Name: かるた
[URL]
Date: 2017年4月22日(土) 20:13
No: 11
(OFFLINE)

 Re: キーボード入力について。

[解決!]

返信ありがとうございます。
マニュアルをしっかり読んで学習します。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: 三郎 & ゲスト[11人]