2

I have got a small problem with my game.

It is not a big deal but I'd love to sort this out.

So this is my input processing function:

void MainGame::processInput()
{
    SDL_Event evnt;

    while (SDL_PollEvent(&evnt)) {
        switch (evnt.type) {
        case SDL_QUIT:
            _gameState = GameState::EXIT;
            break;

        case SDL_MOUSEMOTION:
            break;

        case SDL_KEYDOWN:
            switch (evnt.key.keysym.sym) {
                case SDLK_RIGHT:
                    player.movePlayer(1);
                    break;

                case SDLK_LEFT:
                    player.movePlayer(2);
                    break;
            }
        }
    }
}

and it works just fine, but as you can probably imagine, when I press an arrow key, it moves once (calls the player.movePlayer(); function once) then pauses for a fraction of a second and then continues to read input.

I don't really know how to word it but I hope you know what I mean.

You can also see this effect when you hold any letter in word.

Let's say you press W, it will display the first W instantly and then remaining ones after a fraction of a second something like that:

w wwwwwwwwwwwwwwwwwwwww

I really don't know how to explain it.

So the question is, is there a way to read the raw input from the keyboard so the function will be called continuously straight away?

Danny_ds
  • 11,201
  • 1
  • 24
  • 46
Mac939939
  • 31
  • 1
  • 4
  • 2
    just track keydown and keyup yourself. https://wiki.libsdl.org/SDL_GetKeyboardState The way you're doing it should mostly only be used for typing in letters for a word, not movement control – xaxxon Jan 14 '16 at 01:10
  • 2
    The usual way is to remember whether the key is down or not, and then every frame, if the key is down, move the player. – user253751 Jan 14 '16 at 01:14
  • @xaxxon SDL sets state of keyboard from exactly the same events – keltar Jan 14 '16 at 04:11
  • 1
    the point is to not rely on notifications but instead to poll for the information as needed as to whether it is down or not down – xaxxon Jan 14 '16 at 06:58

1 Answers1

0

I often use code like this:

bool keyboard[1<<30]; // EDIT: as noted in the comments this code might not be the most efficient

and in the event loop

while (SDL_PollEvent(&evnt)) {
    switch (evnt.type) {
    case SDL_QUIT:
        _gameState = GameState::EXIT;
        break;

    case SDL_MOUSEMOTION:
        break;

    case SDL_KEYDOWN:
        keyboard[evnt.key.keysym.sym] = true;
        break;
    case SDL_KEYUP:
        keyboard[evnt.key.keysym.sym] = false;
        break;
    }
    step();
}

and the step function:

void step() {
  if(keyboard[SDLK_RIGHT]) player.movePlayer(1);
  else if(keyboard[SDLK_LEFT]) player.movePlayer(2);
}
Daniel Pérez
  • 1,873
  • 1
  • 17
  • 25
  • 2
    You do realize that `bool keyboard[1<<30]` will consume a minimum of 2^30 bytes (1GiB) of memory? – simon Mar 11 '16 at 22:14
  • That's implementation defined, see http://stackoverflow.com/questions/4897844/is-sizeofbool-defined – simon Mar 12 '16 at 18:07
  • `bool[1<<30]` takes at least 1<<30 bytes -- see [c++ - Why is a boolean 1 byte and not 1 bit of size? - Stack Overflow](https://stackoverflow.com/questions/4626815/why-is-a-boolean-1-byte-and-not-1-bit-of-size) . However there's std::vector as an alternative; and on Linux it may not take that much if allocated dynamically ([virtual memory](https://stackoverflow.com/questions/58523977/is-it-possible-to-allocate-large-amount-of-virtual-memory-in-linux)). – user202729 Oct 03 '20 at 07:56
  • You are using such a big array because the enum values of the keyboard events are large, right? If you are using c++, you are better of using an `unordered_map` to keep the state of the keyboard. – Vallerious Jul 28 '23 at 08:35