0

I'm making a multiplayer game with TCP connection between client and server in C++. The client is ment to detect keypresses (arrowkeys) from the console and send data to the server. The server is supposed to send data to all connected clients about player position etc. This means I need to receive data from the server at anytime whilst detecting whenever an arrowkey is pressed in order to send data back to the server. How do I listen for keyevent and receive data at the same time?

I've tried the following, however the loop gets stuck at _getch(); which waits for input.

int keyListener() {

int keypress = _getch();

return keypress;

}

int main() {

int c = 0;
bool run = true;
while (run) {

    cout << "Listening to socket" << endl;
    
        c = keyListener();
        switch (c) {
        case KEY_UP:
            cout << "UP" << endl;
            break;
        case KEY_DOWN:
            cout << "DOWN" << endl;
            break;
        case KEY_LEFT:
            cout << "LEFT" << endl;
            break;
        case KEY_RIGHT:
            cout << "RIGHT" << endl;
            break;
        default:
            cout << "Listening for keypress" << endl;
            break;
        }

}

return 0;

}

  • Since `_getch()` is a bloking call, you need to do it in a separate thread, while your main thread does whatever is needed from the game. If your TCP API is also blocking, you would need another threat to handle that – Vlad Feinstein Oct 11 '20 at 22:36
  • Ok thanks, will try it out! – Marcus Ström Oct 12 '20 at 10:46
  • @VladFeinstein I can't get two threads to be running at the same time, the thread.join() waits for the thread to finish before keep going with the main thread. How can I get the _getch() to keep on looping while the rest of the main code is being run? – Marcus Ström Oct 12 '20 at 11:47
  • Re: `I can't get two threads to be running at the same time` - that is what threads are for! You don't `join` them until their task is done. See my answer below – Vlad Feinstein Oct 12 '20 at 17:31

1 Answers1

0

You would need more than one book to learn game development. I assume this is just a C++ coding exercise with a "game" theme.

I suggest you create two threads: one to listen to keyboard input and another to handle TCP. You start those threads at the beginning of your game and join them on exit.

The overly simplified game skeleton may look like this:

#include <atomic>
#include <thread>
#include <queue>
#include <mutex>
#include <conio.h>

std::atomic<bool> run = true;
std::queue<int> input;
std::mutex guard;  // to protects input queue

void keyboard()
{
  while (run)
  {
    int keypress = _getch();
    // TODO: if keypress indicates Exit - set run = false;
    // Lock the queue for safe multi-thread access
    {
      const std::lock_guard<std::mutex> lock(guard);
      input.push(keypress);
    }
  }
}

int main()
{
  std::thread keyListener(keyboard);
  // TODO: start your TCP thread
  while (run)
  {
    // 1. Process input (keyboard, mouse, voice, etc.)
    {
      // Lock the queue for safe multi-thread access
      const std::lock_guard<std::mutex> lock(guard);
      // Pop all collected keys and process them
      while (!input.empty())
      {
        int keypress = input.front();
        input.pop();
        // TODO: Send game-related keys to the TCP thread
      }
    }

    // 2. Process TCP input, probably with another queue

    // 3. Update the Game World

    // 4. Display the Game World
  }
  keyListener.join();
  // TODO: join your TCP thread
}
Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27