Sign in to follow this  
treewojima

SDL_EnableKeyRepeat woes

Recommended Posts

I'm trying to figure out the best way to allow key repeat. It seems like SDL_EnableKeyRepeat() is what I'm looking for, but it does nothing. Any suggestions on how to go about collecting or otherwise enabling repeating keyboard input? Here's a bit of my code for the event handler:
void EventManager::start()
{
	if (SDL_EnableKeyRepeat(1, SDL_DEFAULT_REPEAT_INTERVAL) < 0)
		throw SDL_GetError();
}

void EventManager::handleEvents()
{
	Uint8 *keys = SDL_GetKeyState(NULL);

	SDL_Event event;
	EventArguments args;
	while (SDL_PollEvent(&event))
	{
		if (event.type == SDL_QUIT)
		{
			args.type = ET_QUIT;

			ListenerVector::iterator i = quitListeners.begin();
			for (i; i != quitListeners.end(); ++i)
				(*i)->onEvent(args);
		}
		else if (event.type == SDL_KEYDOWN)
		{
			args.type = ET_KEYPRESS;
			args.keyStates = keys;

			ListenerVector::iterator i = keypressListeners.begin();
			for (i; i != keypressListeners.end(); ++i)
				(*i)->onEvent(args);
		}
	}
}
... And for the event subject itself:
class TuxOnTheMove : public Listener
{
public:
	TuxOnTheMove() : x(0), y(0)
	{
		texture = new Texture("res/tux.png");
	}

	void onEvent(EventArguments args)
	{
		if (args.keyStates[SDLK_RIGHT]) x += 5;
		if (args.keyStates[SDLK_LEFT]) x -=5;
		if (args.keyStates[SDLK_DOWN]) y += 5;
		if (args.keyStates[SDLK_UP]) y -= 5;
	}

	int getX() const { return x; }
	int getY() const { return y; }
	Texture *getTexture() const { return texture; }

private:
	int x, y;
	Texture *texture;
};
So I'm checking for a keydown event, and then I dispatch it out to the input listeners, which check SDL_GetKeyState for anything that applies to them. Is this method of event handling the cause of my problem? I'm hoping the solution is something simple, so I don't have to rewrite all my event code.

Share this post


Link to post
Share on other sites
I am going to tell you how I handle this is issue. Hopefully, it will be suitable to you so that you can apply it to yr code.

I do the same as you; however, I make the following modification:

while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
// quit stuff here.
}

else if (event.type == SDL_KEYDOWN)
{
// process key down events.
}

else if (event.type == SDL_KEYUP)
{
// process key up events.
}
}

So you will process both the keydown as well as the keyup event. Then you should have a boolean like:

bool rightArrow = false;

So on a keydown event for the right arrow (do same for other keys, obviously), instead of changing the tux on the move guy's position, you are just setting this bool rightArrow to true; on the keyup event you set this to false.

Then, in the tux guy's update method you could have something like:

void TuxGuy::update()
{
unsigned int MOVE = 5; // the sprite's movement.
if ( rightArrow ) x += MOVE;
if ( leftArrow ) x -= MOVE;
if ( upArrow ) y -= MOVE;
if ( downArrow ) y += MOVE;
}

So basically, you separate keeping track of the key states, via keydown & keyup events, from the entity's update logic. Hopefully, this will be helpful.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this