Почему мое нажатие на клавиатуру оценивается как ложное

Я новичок на C ++, пишущий игру про змейку. Вся программа отлично рисует доску, фрукты и голову змеи, однако я не могу изменить координаты головы змеи с помощью функции нажатия на клавиатуру. При прохождении функции ввода, которая получает нажатия клавиш для движения змеи, кажется, что if (kbhit) оценивается как false при запуске программы, в чем моя ошибка и как я могу заставить голову змеи двигаться?

Спасибо.

#include <iostream>
#include <stdlib.h> 
#include <time.h>
#include <windows.h>
#include <conio.h>
using namespace std;

int X, Y, fruitX, fruitY;
enum eDir { STOP = 1, UP = 2, DOWN = 3, RIGHT = 4, LEFT = 5 }; //declare variables
eDir direction;
const int height = 20;
const int width = 20;
int board[height][width];
bool gameOver;

void setup()
{
    gameOver = false;
    srand(time(NULL));          // initilize game set up
    fruitX = (rand() % width);
    fruitY = (rand() % height);
    X = height / 2;
    Y = width / 2;
    direction = STOP;
    int board[height][width];
};

void draw()
{
    system("cls");

    for (int i = 0; i < width + 2; i++)
        cout << '#';

    cout << endl;

    for (int i = 0; i < height; i++)    //loop through matrix to draw board
    {
        for (int j = 0; j < width; j++)
        {

            if (j == 0)
                cout << '#';
            if (i == Y && j == X) // draw snake head
                cout << 'T';
            else if (i == fruitY && j == fruitX) // draw fruit
                cout << 'F';
            else
                cout << ' ';

            if (j == width - 1)
                cout << '#';
        }
        cout << endl;
    }

    for (int i = 0; i < width + 2; i++)
        cout << '#';

    cout << endl;
};

void input()
{
    if (_kbhit())
    {
        switch (_getch())
        {
        case 'w':
            direction = UP;
            break;
        case 's':
            direction = DOWN;
            break;
        case 'a':
            direction = LEFT;
            break;
        case 'd':
            direction = RIGHT;
            break;
        default:
            break;
        }

    }
};

void logic()
{
    switch (direction)
    {
    case UP:
        Y--;
        break;
    case DOWN:
        Y++;
        break;
    case LEFT:
        X--;
        break;
    case RIGHT:
        X++;
        break;
    default:
        break;
    }
};

int main()
{
    setup();
    while (!gameOver)
    {
        draw();
        input();
        logic();
        return 0;
    }
};

person twillycodes    schedule 22.04.2018    source источник
comment
Как вы установили, что результат теста ложный? Вы добавляли логи? Вы говорите, что, похоже, он оценивается как ложный, но не сообщаете нам, что вы на самом деле наблюдали, а просто (возможно, неверный) вывод, который вы сделали из этого. Это все равно, что сказать вашему доктору, что у меня низкий уровень кортизона. Если вы не скажете ему, какие симптомы заставляют вас так думать, как он может понять, что с вами не так?   -  person David Schwartz    schedule 22.04.2018
comment
Кроме того, ваш код не имеет особого смысла. Вы постоянно очищаете экран - как вообще можно что-то видеть?   -  person David Schwartz    schedule 22.04.2018
comment
Вы return 0; из while цикла в main, это означает, что он выполняется ровно 1 раз до завершения программы   -  person Killzone Kid    schedule 22.04.2018
comment
@KillzoneKid Это звучит как ответ для меня   -  person Yann    schedule 22.04.2018
comment
@Yann Я не читал вопрос, только отформатировал и заметил это.   -  person Killzone Kid    schedule 22.04.2018
comment
@KillzoneKid В таком случае, спасибо за (возможно) решение проблемы беглым взглядом. Вы получили бы false от _kbhit, если бы у вас не было возможности нажать клавишу, потому что вы ждали запуска отладчика, и в вашем первом кадре вы попали в точку останова   -  person Yann    schedule 22.04.2018
comment
@Yann, я стер возвращение 0, но программа рисует доску снова и снова бесконечно, также X и Y не меняются   -  person twillycodes    schedule 22.04.2018
comment
на самом деле X и Y теперь меняются, однако они не останутся на том же игровом поле, так как они продолжают проходить через розыгрыш.   -  person twillycodes    schedule 22.04.2018
comment
@ Янн, спасибо!   -  person twillycodes    schedule 22.04.2018
comment
Да, с возвратом, перемещенным вне времени, это нормально работает на моей машине. Вы определенно захотите ограничить его скорость, так как в настоящее время змея движется так же быстро, как ваш процессор. Кроме того, в игровых движках вы, как правило, запускаете отрисовку после обновления, в противном случае игра отображает ввод последних кадров, что действительно не отвечает. Ничего страшного в этой игре, но позже это станет проблемой.   -  person Yann    schedule 22.04.2018


Ответы (1)


Во-первых, вы делаете return 0; внутри своего игрового цикла, который завершает программу только после одной итерации, которую, как я полагаю, вы не планировали.

Я сделал змейку аналогичным способом, и моя выглядит так:

bool play = true;

while(play) {
    while (_kbhit) {
        switch (_getch) {
        case 'w':
            //code
            break;
        case 's':
            //code
            break;
        case 'a':
            //code
            break;
        case 'd':
            //code
            break;
        }
    }
}

Этот метод сработал для меня, и я думаю, единственная разница в том, что я использовал цикл while вместо if.

person TNTFreaks    schedule 22.04.2018