[SDL] Any idea how to make input more responsive?

Started by
2 comments, last by rip-off 12 years, 9 months ago
Im just finding that for some reason input handling via SDL is quite stiff or maybe Im not doing it right

heres what I have so far



SDL_PollEvent(&keyboard_event);
{
if ( keyboard_event.type == SDL_KEYDOWN )
{
switch ( keyboard_event.key.keysym.sym )
{
case SDLK_LEFT:
launcher.SetVelocityX(-MOVE_SPEED);
break;

case SDLK_RIGHT:
launcher.SetVelocityX(MOVE_SPEED);
break;
}

last_key = keyboard_event.key.keysym.sym;
return;
}
else
if ( keyboard_event.type == SDL_KEYUP )
{
switch ( keyboard_event.key.keysym.sym )
{
case SDLK_LEFT:
launcher.SetVelocityX(0);
break;
case SDLK_RIGHT:
launcher.SetVelocityX(0);
break;
}

return;
}
}



whenever I switch keys my object stops moving for a couple of seconds , then it resumes movement
Advertisement

Im just finding that for some reason input handling via SDL is quite stiff or maybe Im not doing it right

heres what I have so far



SDL_PollEvent(&keyboard_event);
{
if ( keyboard_event.type == SDL_KEYDOWN )
{
switch ( keyboard_event.key.keysym.sym )
{
case SDLK_LEFT:
launcher.SetVelocityX(-MOVE_SPEED);
break;

case SDLK_RIGHT:
launcher.SetVelocityX(MOVE_SPEED);
break;
}

last_key = keyboard_event.key.keysym.sym;
return;
}
else
if ( keyboard_event.type == SDL_KEYUP )
{
switch ( keyboard_event.key.keysym.sym )
{
case SDLK_LEFT:
launcher.SetVelocityX(0);
break;
case SDLK_RIGHT:
launcher.SetVelocityX(0);
break;
}

return;
}
}



whenever I switch keys my object stops moving for a couple of seconds , then it resumes movement


Thats because you set velocity to 0 when a key is released.

consider this:

you press left, then press the right key (then you will move right), when left is released you will stop, you'll start moving again once the keyrepeat kicks in and you get another keydown event. (This takes some time), if you switch key too fast you basically get the down and up events on the same frame and it can take up to a few seconds before you get a new down event

a better option is to have two bool variables left and right and set those on keyup keydown

then in your update method you simply check those to determine how to move.

(as a rule of thumb you shouldn't have any game logic in your event handling section, it just makes a mess)
[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!
THANK YOU!

Im just finding that for some reason input handling via SDL is quite stiff or maybe Im not doing it right
...
whenever I switch keys my object stops moving for a couple of seconds , then it resumes movement
[/quote]
You have a bug in your code. SDL does not introduce any particular latency into your input, apart from the latency inherent in only processing input frame by frame.

The most obvious bug is that you aren't dealing with input in a loop. This means that if you have 50 events queued up, it will take you 50 frames before you'll process the last event. This wouldn't explain why your latency is in the order of seconds, as you'd struggle to generate enough events with such consistency.

You should also ensure you are checking the return value of SDL_PollEvent(), you should not be testing the values of the variables unless it returns non-zero. I also hope you are detecting SDL_QUIT events. I also sense the possibility in your code that you have multiple SDL_PollEvent() loops. This is rarely a good idea, I'd recommend you only have one place in your code where you read events from SDL, otherwise you'll get obscure bugs where an event you expect in one loop is read and discarded by a second loop.

Here is how I would usually handle this:

void handleKey(Launcher &launcher, const SDL_KeyBoardEvent &event, bool keyPressed)
{
int modifier = (keyPressed ? 1 : -1);
switch(event.keysym.sym)
{
case SDLK_LEFT:
launcher.AddVelocityX(modifier * -MOVE_SPEED);
break;

case SDLK_RIGHT:
launcher.AddVelocityX(modifier * MOVE_SPEED);
break;
}
}

void example(Launcher &launcher)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
// ...
break;

case SDL_KEYUP:
handleKey(launcher, event.key, true);
break;

case SDL_KEYDOWN:
handleKey(launcher, event.key, false);
break;

// Other cases ...
}
}
}

Note that I've changed SetVelocityX() to AddVelocityX(). This solves another bug which your code would have. Imagine you press left - the sprite starts to move left. Now you press right, so the sprite reverses direction. However, if you now release the left key, the velocity is zeroed. This results in an odd situation where the player is still pressing right, but the sprite isn't moving.

With the additive version, once the player is pressing both left and right, the sprite stops. This makes sense, because it isn't clear which direction the player intends to move. Once one of the keys is released, the sprite will move in the direction of the pressed key.

This topic is closed to new replies.

Advertisement