SDL event behavior

I was wondering if this is normal behavior, and how should I get around
it?

First, I have key repeating enabled. In my input code, I poll the input,
check for SDL_KEYDOWN, and if a key is down, I check to see if it’s
SDLK_LEFT, if so, I rotate this ship on the screen.

This works great. HOWEVER, if I hold left, it starts rotating left, then
press right, while still holding left, it begins to rotate right. This
is all fine, however, when I lift up from the right key, while still
pressing the left key, it does not continue rotating left as it should.
I have to completely lift my finger off left and press it again to get
left rotations again.

This is not the behavior I want. Is this a bug in SDL? Shouldn’t it
continue to say the left key is pressed when while I’m still holding it?–
Chris Thielen <@Christopher_Thielen>

I was wondering if this is normal behavior, and how should I get
around it?

First, I have key repeating enabled. In my input code, I poll the
input, check for SDL_KEYDOWN, and if a key is down, I check to see if
it’s SDLK_LEFT, if so, I rotate this ship on the screen.

This works great. HOWEVER, if I hold left, it starts rotating left,
then press right, while still holding left, it begins to rotate right.
This is all fine, however, when I lift up from the right key, while
still pressing the left key, it does not continue rotating left as it
should. I have to completely lift my finger off left and press it
again to get left rotations again.

This is not the behavior I want. Is this a bug in SDL? Shouldn’t it
continue to say the left key is pressed when while I’m still holding
it?

It’s not a bug; pressing another key will interrupt the key repeat for
the first key that’s down. This is true everywhere – try it out any
place where you can type text. Hold down a key: aaaaa, then hold down
another key: bbbbb, then release the second key: .

The usual way of handling input for games is to disable key repeating,
and just catch the KEYDOWN/KEYUP event and use a flag to keep track of
the state of the key. You then do the sprite movement outside of the
event handler code based on what controls are currently being applied.

Typically, this is done using a bitfield to save memory.

For example:

#define KEY_LEFT (1 << 0) /* you can also count in powers of two /
#define KEY_RIGHT (1 << 1) /
yourself here, but i find this more /
#define KEY_UP (1 << 2) /
readable. YMMV. */
#define KEY_DOWN (1 << 3)

int keys = 0;

while (SDL_PollEvent(&event) > 0)
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_LEFT: /* set flag to indicate left arrow is down /
keys |= KEY_LEFT;
break;
case SDLK_RIGHT: /
set flag to indicate right arrow is down /
keys |= KEY_RIGHT;
break;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_LEFT: /
clear left arrow flag /
keys &= ~KEY_LEFT;
break;
case SDLK_RIGHT: /
clear right arrow flag */
keys &= ~KEY_RIGHT;
break;
}
break;
}
}

if (keys & KEY_LEFT)
/* rotate ship “left” /
if (keys & KEY_RIGHT)
/
right ship “right” */

Hope that’s clear enough.
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030114/4d729e6d/attachment.pgpOn Mon, Jan 13, 2003 at 08:16:16PM -0800, Chris Thielen wrote:

Hello Michael,

Tuesday, January 14, 2003, 12:15:40 PM, you wrote:

MA> if (keys & KEY_LEFT)
MA> /* rotate ship “left” /
MA> if (keys & KEY_RIGHT)
MA> /
right ship “right” */

MA> …
MA> Hope that’s clear enough.

Thank you for perfect solution, I was trying to make something like
that couple of weeks ago but got stuck and dropped it leaving jerky
controls in my game. That solves one of the last bug ;)–
Lynx,
http://dotNet.lv mailto:@Anatoly_R

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1On Tuesday 14 January 2003 11:15, Michael Alger wrote:

The usual way of handling input for games is to disable key repeating,
and just catch the KEYDOWN/KEYUP event and use a flag to keep track of
the state of the key. You then do the sprite movement outside of the
event handler code based on what controls are currently being applied.

Typically, this is done using a bitfield to save memory.

Note that SDL already does this for you. Check out the function
SDL_GetKeyState().

cu,
Nicolai
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+JCZKsxPozBga0lwRAs58AJ45Aeukd4NgvsRmv++PsWf595petgCfcW3i
lclxCy5fCy0i3AmZqH/qwwY=
=ihzp
-----END PGP SIGNATURE-----

There is an easier way to do this: use SDL_GetKeyState().

Uint8 *keys;

SDL_PumpEvents();
keys = SDL_GetKeyState(NULL);

if(keys[SDLK_LEFT])
/* rotate ship left */

Hope that helps.On Tue, Jan 14, 2003 at 06:15:40PM +0800, Michael Alger wrote:

On Mon, Jan 13, 2003 at 08:16:16PM -0800, Chris Thielen wrote:
The usual way of handling input for games is to disable key repeating,
and just catch the KEYDOWN/KEYUP event and use a flag to keep track of
the state of the key. You then do the sprite movement outside of the
event handler code based on what controls are currently being applied.

Typically, this is done using a bitfield to save memory.

For example:

#define KEY_LEFT (1 << 0) /* you can also count in powers of two /
#define KEY_RIGHT (1 << 1) /
yourself here, but i find this more /
#define KEY_UP (1 << 2) /
readable. YMMV. */
#define KEY_DOWN (1 << 3)

int keys = 0;

while (SDL_PollEvent(&event) > 0)
{
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_LEFT: /* set flag to indicate left arrow is down /
keys |= KEY_LEFT;
break;
case SDLK_RIGHT: /
set flag to indicate right arrow is down /
keys |= KEY_RIGHT;
break;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_LEFT: /
clear left arrow flag /
keys &= ~KEY_LEFT;
break;
case SDLK_RIGHT: /
clear right arrow flag */
keys &= ~KEY_RIGHT;
break;
}
break;
}
}

if (keys & KEY_LEFT)
/* rotate ship “left” /
if (keys & KEY_RIGHT)
/
right ship “right” */


Ivan Stankovic, @Ivan_Stankovic