_getch как будто останавливает мою программу
Название довольно наглядно. По сути, я делаю Space Invaders в окне консоли в C++, это называется ASCII invaders. Кажется, в игре все работает нормально, за исключением одной серьезной проблемы: _getch приостанавливает работу программы. Я вызываю _kbhit, чтобы проверить, вводит ли игрок данные игрока, и если да, то использую _getch, чтобы получить ключ и действовать правильно. Игрок перемещается влево / вправо очень хорошо, но когда игрок нажимает "Пробел" или стреляет, программа приостанавливается до тех пор, пока вы снова не нажмете "Пробел", в этот момент он также будет стрелять.
Очевидно, что игрок не хочет этого в игре. Так что хотелось бы знать, как это исправить. Вот где это называется:
/***************************************/
/* move_player(); */
/* Calculates player movement */
/*Returns weather or not toQuitTheGame */
/***************************************/
bool move_player()
{
bool ret = false;
//If a key is pressed
if (_kbhit())
{
//Get key
_getch();
int key = _getch();
//Check is the player moves left
if (key == LEFT && object_handle.player_obj.x > 0)
{
//Move left
object_handle.player_obj.x -= 1;
}
//Check is the player moves right
if (key == RIGHT && object_handle.player_obj.x < 79)
{
//Move right
object_handle.player_obj.x += 1;
}
//Check is the player is shooting
if (key == SHOOT)
{
//shoot by creating the bullet above the player
object_handle.bullet_obj.x = object_handle.player_obj.x;
object_handle.bullet_obj.y = object_handle.player_obj.y - 1;
object_handle.bullet_obj.active = true;
}
//Weather or not to kill the program
if (key == VK_ESCAPE)
{
ret = true;
}
else
{
ret = false;
}
}
return ret;
}
В качестве примечания, если вы просто прокручиваете мысль "Это много кода... Я не хочу иметь дело с этим". (Я делаю это иногда - не придираюсь к вам), обратите внимание, это не так уж и много, я просто использую комментарии и много пустого пространства.
И если вы хотите знать, вот вся "основная" функция.
int main()
{
bool quit = false;
object_handle.set_info();
//Display main manu
menu();
//Main game loop
while(!quit)
{
//Update past object variables
object_handle.xy_update();
//Calculate player movements
quit = move_player();
//Calculate bullet movements
handle_objects();
//Finally, update the screen
screen_update();
//DEBUG CODE
debug();
//Display score/stats
stats();
//Wait a given time before continuing the loop
Sleep(INTERVAL);
}
cout << "\n\n\n\n\nBye" << endl;
Sleep(1000);
return 0;
}
Я включил все необходимые библиотеки, я не получаю ошибок компиляции.
Ах, да, прежде чем я забуду. Вот константы:
/******************CONSTANTS********************/
const int ENEMY_COUNT = 15;
const int INTERVAL = 250;
const int LEFT = 75;
const int RIGHT = 77;
const int SHOOT = VK_SPACE;
const int BULLET_SPEED = 8;
/***********************************************/
Любая помощь очень ценится!
3 ответа
Как объяснено в документации When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.
Итак, вам нужно проверить, что возвращается, чтобы узнать, следует ли вам снова вызывать функцию.
Вот пример того, что вы должны быть в состоянии адаптироваться к вашим потребностям:
#include <conio.h>
#include <iostream>
int main()
{
std::cout << "Type stuff, press x to quit.\n";
int count = 0;
for(;;)
{
//To show the loop isn't blocked
if((++count % 1000) == 0)
{
std::cout << ".";
}
if(_kbhit())
{
int key = _getch();
if(key == 0 || key == 0xE0)
{
key = _getch();
}
std::cout << "\nKeycode: " << key << "\n";
if(key == 'x')
{
break;
}
}
}
return 0;
}
Вы также можете рассмотреть ReadConsoleInput
Семейство функций, так как это дает вам больше гибкости. Вот пример из MSDN.
Попробуйте изменить:
_getch();
int key = _getch();
чтобы:
int key = _getch();
в вашем move_player
функция.
Когда вы звоните _getch()
дважды, в первый раз, он не записывает ключ, просто висит там, пока вы не нажмете клавишу снова, потому что тогда _getch()
присваивается переменной key
, Следовательно, вы должны удалить шальные _getch()
в вашем move_player()
функция.
Как уже упоминалось @RetiredNinja, вам нужно позвонить _getch()
дважды, так что вам нужно установить проверку на первом _getch()
установить, нажали ли вы клавишу алфавита или специальную клавишу.