Performance Optimization With Checking for user input (Keyboard/Mouse Input)

Hey there!,

Alright, well my question is "What is your way of getting keyboard input from a user" I am programming small programs that need to check if certain keys are being pressed (Like a small video game). My current way of checking for input is a switch case structure. like the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
if (event.type == SDL_KEYUP)
			{
				switch(event.key.keysym.sym)
				{
				case SDLK_UP:
					arrowUp = false;
					break;

				case SDLK_RIGHT:
					arrowRight = false;
					break;

				case SDLK_DOWN:
					arrowDown = false;
					break;

				case SDLK_LEFT:
					arrowLeft = false;
					break;

				case SDLK_a:
					keyA = false;
					break;

				case SDLK_d:
					keyD = false;
					break;

				default:
					break;
				}		

(I think I might be missing a curly brace I know..)
But I do not find this to be of any great performance to have to check for every key. Is there a better way of doing so?

I am using SDL to gather keyboard input.

Thanks for any advice!
Is there a better way of doing so?

Nope, there are fancier ways of doing it but they are all essentially checking each key for it's current state and reacting accordingly. Also this one of those cases where you may not want to break from the switch when a single condition is met. Think about this: with your current code I cannot move up and right at the same time because the switch will see that up is pressed and never check for right.

EDIT: I also wanted to mention that this is one of those MANY cases in C\C++ where being able to compile more then one source file is a boon. Just write all of the stuff once in it's own header file and use that as a template for all of your future projects.
Last edited on
Also this one of those cases where you may not want to break from the switch when a single condition is met. Think about this: with your current code I cannot move up and right at the same time because the switch will see that up is pressed and never check for right.


Actually this is probably wrong. If he's getting SDL events, it will probably send a different event each time. And besides even if he did it the then the switch would just set everything to false instead of just the key that was released.
Actually this is probably wrong. If he's getting SDL events, it will probably send a different event each time. And besides even if he did it the then the switch would just set everything to false instead of just the key that was released.

I see, I thought I saw if statements for each check. He probably would have to rewrite a lot more then just the breaks. My point still stands the switch case won't work how it's written.
I don't think there is anything wrong with what he is doing. He probably also check for SDL_KEYDOWN events and set the variables to true accordingly.

If you just want to check if a key is down you can use SDL_GetKeyState to get a pointer to an array that contain information for each key whether it's down or not. http://www.libsdl.org/cgi/docwiki.cgi/SDL_GetKeyState

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
Uint8* keystate = SDL_GetKeyState(NULL);

if (keystate[SDLK_RIGHT])
{
	// right arrow key is down
}

if (keystate[SDLK_LEFT])
{
	// left arrow key is down
}

...

EDIT: Fixed the function argument ^
Last edited on
Those "if" statements make all of the difference though. If should be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Uint8* keystate = SDL_GetKeyState(int *numkeys);

if (keystate[SDLK_RIGHT])
{
        arrowRight = true;
	// right arrow key is down
}

if (keystate[SDLK_LEFT])
{
        arrowLeft = true;
	// left arrow key is down
}

...


Which makes the switch statement kind of pointless. By breaking from the switch statements he's telling the program to skip every check after he finds one that matches a case.
If he is using SDL_GetKeyState there is probably no need to use arrowRight, arrowLeft, etc. because that information is already available in the array returned by SDL_GetKeyState.
I was honestly just going off the code he had above. I haven't even looked at SDL since I started SFML.
It will work with the switch, he just need to process the entire event stack.

they are all essentially checking each key for it's current state and reacting accordingly.
Or let the key that changes its state informs you.
Last edited on
Peter, I think you're right and I like your idea. You are correct about me having the separate if control to check for the key's being up. I find that completely pointless to have the program see that all the keys are up and than set the keys to being false every single time. (I set the key false for not being pressed and true for being pressed)

Is there a way to do a switch so when I do let go of the key it will switch it back to false and not set it to false again and again throughout the program.

Here is my complete code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 while(SDL_PollEvent(&event)) 
		{
			if (event.type == SDL_KEYDOWN)
			{
				switch(event.key.keysym.sym)
				{
				case SDLK_UP:
					arrowUp = true;	
					break;

				case SDLK_RIGHT:
					arrowRight = true;
					break;

				case SDLK_DOWN:
					arrowDown = true;
					break;

				case SDLK_LEFT:
					arrowLeft = true;
					break;

				case SDLK_a:
					keyA = true;
					break;

				case SDLK_d:
					keyD = true;
					break;

				case SDLK_ESCAPE:
					done = true;
					break;

				default:
					break;
				}
			} //End if KeyDown

			if (event.type == SDL_KEYUP)
			{
				switch(event.key.keysym.sym)
				{
				case SDLK_UP:
					arrowUp = false;
					break;

				case SDLK_RIGHT:
					arrowRight = false;
					break;

				case SDLK_DOWN:
					arrowDown = false;
					break;

				case SDLK_LEFT:
					arrowLeft = false;
					break;

				case SDLK_a:
					keyA = false;
					break;

				case SDLK_d:
					keyD = false;
					break;

				default:
					break;
				}		
			} //End if KeyUp
		} 
Include Syntax wrote:
Is there a way to do a switch so when I do let go of the key it will switch it back to false and not set it to false again and again throughout the program.

As I said, you can use SDL_GetKeyState. You can use it instead of having the switch statements. It's exactly the same information you try to keep track of so why not use it when SDL already have that information.


Checking if a key is down is good for things that should repeat itself as long as a key is hold down, like moving a character, loading up power to kick a ball harder, etc. It is not very good for things like navigating a menu, toggle full screen mode, typing text, etc. In these cases it is much better to check for the SDL_KEYDOWN event because you are interested in that the user pressed that button, not for how long he pressed the button.
Example:
User should press F11 to toggle full screen mode. If you handle that something like this
1
2
3
4
if (keystate[SDLK_F11])
{
	toggleFullScreenMode();
}

it will behave very buggy. If the user press F11 but release it fast enough so that the key is never actually pressed down during the time when the if statement is executed the program will miss that the key was pressed down and nothing will happen. If the user press F11 but holds it down for some time the code inside the if statement will run each time as long as the key is hold down. This will cause the program to switch between full screen mode and window mode like crazy. If you instead react on the SDL_KEYDOWN event it will always call the function exactly once each time the user press F11 regardless how long he hold the key down.
1
2
3
4
5
6
7
8
9
10
11
if (event.type == SDL_KEYDOWN)
{
	switch(event.key.keysym.sym)
	{
	...
	case SDLK_F11:
		toggleFullScreenMode();
		break;
	...
	}
}
Last edited on
Topic archived. No new replies allowed.