2015-01-24 5 views
0

Название довольно наглядное. В основном, я делаю Space Invaders в консольном окне на C++, это называется ASCII-захватчиками. Кажется, что в игре все работает отлично, за исключением одной серьезной проблемы, _getch приостанавливает программу. Я звоню _kbhit, чтобы проверить, входит ли игрок в вход игрока, тогда, если это так, я использую _getch, чтобы получить ключ и действовать правильно. Игрок перемещается влево/вправо очень хорошо, но когда игрок нажимает «Пробел» или снимает, программа останавливается, пока вы снова не нажмете «Пробел», в этот момент она также будет стрелять._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; 
/***********************************************/ 

Любая помощь очень ценится!

+2

Почему вы вызываете _getch() дважды? – Axalo

+0

Вам нужно позвонить ему дважды, чтобы получить клавиши со стрелками, но вы можете обнаружить это и сделать это условно. Вероятно, вам будет лучше с ReadConsoleInput, как описано [в этом вопросе/ответе] (http://stackoverflow.com/questions/2067893/c-console-keyboard-events/). –

ответ

0

изменение Try:

_getch(); 
int key = _getch(); 

к:

int key = _getch(); 

в вашей move_player функции.

+0

Почему? Как этот подход разрешает чтение функциональных клавиш и т. Д.? – hyde

0

При вызове _getch() дважды, первый раз, он не записывает ключ, просто висит там, пока вы снова не нажмете клавишу, потому что тогда _getch() присваивается переменной key. Следовательно, вы должны удалить блуждающий _getch() в своей функции move_player().

Как уже упоминалось @RetiredNinja, вам нужно позвонить _getch() в два раза, так что вам необходимо установить проверку на первом _getch() установить, если вы нажали алфавит ключ, или специальный ключ.

+2

Спасибо вам, ребята! Это сработало. Я читал где-то, что вам нужно позвонить ему дважды, так что, наверное, мне следовало бы прочитать немного больше. – null

+0

Вам нужно позвонить ему дважды, чтобы получить некоторые клавиши, включая клавиши со стрелками. –

+0

@PaoloMazzonJr. Если это сработало, примите ответ. Это поможет другим зрителям вопроса. – shauryachats

1

Как объяснено в the documentationWhen 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 семейства функций, поскольку она дает вам немного больше гибкости. Вот example from MSDN.

Смежные вопросы