Multi-keypress movement in SDL2

Started by
6 comments, last by BiiXteR 8 years ago

I'm having a problem with creating movement for my box.

If I press let's say up, and then right, I would like my character to increment the x and y position so it moves to the top right (2D view).

Instead, it stops moving up and just moves right instead.

This is how my keypress checking function works :


switch (Input::eventHandler.type)
{


case SDL_QUIT:
    SDL_Quit();
    exit(0);
    break;


case SDL_KEYDOWN:


switch (Input::eventHandler.key.keysym.sym)
{


    case SDLK_UP:
        SpriteManager::GetSprite("sprite1")->Move(0, -1 * Time::GetDeltaTime());
        break;


    case SDLK_DOWN:
        SpriteManager::GetSprite("sprite1")->Move(0, 1 * Time::GetDeltaTime());
        break;


    case SDLK_RIGHT:
        SpriteManager::GetSprite("sprite1")->Move(1 * Time::GetDeltaTime(), 0);
        break;


    case SDLK_LEFT:
        SpriteManager::GetSprite("sprite1")->Move(-1 * Time::GetDeltaTime(), 0);
        break;

    default:
        break;

And here's how I move my box :


void Sprite::Move(long offsetX, long offsetY)
{
    x += offsetX;
    y += offsetY;
}

Advertisement
don't move things when you process the events, flag the keys as pressed on key down, unflag on key up.

case SDL_KEYDOWN:
    key_pressed[...keysym.sym] = 1;
    break;
case SDL_KEYUP:
    key_pressed[...keysym.sym] = 0;

...

gameloop ...
    dt = Time::GetDeltaTime();
    dx = dt * (key_pressed[SDLK_RIGHT] - key_pressed[SDLK_LEFT])
    dy = dt * (key_pressed[SDLK_DOWN] - key_pressed[SDLK_UP])
    sprite->Move(dx, dy);
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

don't move things when you process the events, flag the keys as pressed on key down, unflag on key up.

This is very true, and I want to add some stuff just in case you mess up something.

1. Make a separate function for your logic, for example update() or logic() and put the movement there.
2.Make a separate function for event handling for example, handle_events(), and don't do logic in handle_events().
3.Declare booleans for all the keys you use and set them to false and in your handle_events(), instead of writing "if something is pressed, move there" just say: if( SDLK_UP is pressed ) { upKey = true; } .
4.And later in your logic() or update() function, you do this: If( upKey == true ) { go up/forward }.
5.And don't forget to say: if( upKey is no longer pressed ) { upKey = false }.

don't move things when you process the events, flag the keys as pressed on key down, unflag on key up.

This is very true, and I want to add some stuff just in case you mess up something.

1. Make a separate function for your logic, for example update() or logic() and put the movement there.
2.Make a separate function for event handling for example, handle_events(), and don't do logic in handle_events().
3.Declare booleans for all the keys you use and set them to false and in your handle_events(), instead of writing "if something is pressed, move there" just say: if( SDLK_UP is pressed ) { upKey = true; } .
4.And later in your logic() or update() function, you do this: If( upKey == true ) { go up/forward }.
5.And don't forget to say: if( upKey is no longer pressed ) { upKey = false }.

What if I would like to check if the key was released recently, maybe the previous frame.

How would I do that?

Create a second copy of all the key variables and do checks?

Or is there better ways to do it?

case SDL_KEYDOWN is when a particular key has been pressed.
case SDL_KEYUP is when a key has been released.

so you say something like that:

if( event.type == SDL_KEYUP )

{

if( event.key.keysym.sym == SDLK_UP )

{

upKey = false;

}

}

If the upkey is released, set the boolean to false.

Also be sure you handle cases like right and left being pressed simultaneously, up/down to be pressed simultaneously, etc.

The details will depend on the game and what the buttons are expected to do. Whatever it is, make it sane.

case SDL_KEYDOWN is when a particular key has been pressed.
case SDL_KEYUP is when a key has been released.

so you say something like that:

if( event.type == SDL_KEYUP )

{

if( event.key.keysym.sym == SDLK_UP )

{

upKey = false;

}

}

If the upkey is released, set the boolean to false.

Ohh okay, didn't know KEYUP existed. Thank you! :)

Also be sure you handle cases like right and left being pressed simultaneously, up/down to be pressed simultaneously, etc.

The details will depend on the game and what the buttons are expected to do. Whatever it is, make it sane.

For some reason my SDL_KEYDOWN seems to be generating SDL_KEYUP even though I haven't released any key? Weird..

This topic is closed to new replies.

Advertisement