SDL key array strange behavior

Hello! i am trying to make my first pong in c++ with SDL.
the game is running and you can play but i got two problems.

The key array have a very strange behavior. I cant hold down keys just press them once. And most strange of all is that, I have tried exactly same code in another program and it worked just fine! which confuses me alot.

And for some reason i tried declare the array in the main function(Not inside the loop) and when i run it, it acted even more strange, it said that all keys were pressed all the time, and when i pressed quit i got runtime errors with the array.

The game works just fine if i declare the array globaly. Just cant hold down keys.


And the second error is that when i go into fullscreen mode i get massive flickeriing, you cant even see what is going on.

Well, that was my problems, here comes the code.

Thanks in advance!

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_Image.h>
#include "paddle.h"
#include "ball.h"
#define FPS 30

using namespace std;

SDL_Surface * screen;
SDL_Event event;
Uint32 start;

bool keys[274] = {false};
bool fullscreen = false;
bool running = true;

bool init();

int main(int argc,char** argv)
{
	if((!init())){SDL_Quit(); return 0;}
	paddle paddle1(1);
	paddle paddle2(2);
	ball Ball;

	while(running)
	{
		start = SDL_GetTicks();
		while(SDL_PollEvent(&event))
		{
			switch(event.type)
			{
			case SDL_QUIT:
				running = false;
				break;
			case SDL_KEYUP:
				keys[event.key.keysym.sym] = false;
				break;
			case SDL_KEYDOWN:
				if(event.key.keysym.sym == SDLK_f){fullscreen = (!fullscreen);}
				keys[event.key.keysym.sym] = true;
				break;
			}
		}
		if(keys[SDLK_w]){cout << "W IS DOWN" << endl; paddle1.Up();}
		if(keys[SDLK_s]){cout << "S IS DOWN" << endl; paddle1.Down();}
		if(keys[SDLK_UP]){cout << "ARROWUP IS DOWN" << endl;paddle2.Up();}
		if(keys[SDLK_DOWN]){cout << "ARROWDOWN IS DOWN" << endl; paddle2.Down();}
		if(keys[SDLK_ESCAPE]){running = false; break;}

		if(fullscreen){screen = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN|SDL_RESIZABLE);}else{screen = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);}

		SDL_FillRect(screen,NULL,NULL);

		paddle1.Blit();
		paddle2.Blit();
		Ball.update(paddle1.ReturnRect(),paddle2.ReturnRect());

		SDL_Flip(screen);
		if(1000/FPS > SDL_GetTicks() - start){SDL_Delay(1000/FPS - (SDL_GetTicks() - start));}
	}
	SDL_Quit();

	return 0;
}

bool init(){

	if(SDL_Init(SDL_INIT_EVERYTHING) == -1){
		std::cout << "Could not initialize sdl" << std::endl;
		return false;
	}
	std::cout << "SDL initilized" << std::endl;

	screen = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);

	if(screen == NULL){
		std::cout << "Could not setup screen" << std::endl;
		return false;
	}

	std::cout << "Screen is setup" << std::endl;


	if(TTF_Init() == -1){
		std::cout << "Could not initialize ttf" << std::endl;
		return false;
	}

	std::cout << "TTF initilized" << std::endl;

	SDL_WM_SetCaption("Pong",NULL);

	return true;

}
Last edited on
SDL already keeps track of such an array so just use SDL_GetKeyState: http://www.libsdl.org/cgi/docwiki.cgi/SDL_GetKeyState

Don't call SDL_SetVideoMode every frame. That is probably what causes the flickering. Only call it at the beginning of the program and when you change from/to fullscreen.

Last edited on
SDL_Delay(1000/FPS - (SDL_GetTicks() - start));This could cause problems if 1000/FPS < (SDL_GetTicks() - start) because then you get a very large value and the program will sleep for very long time.

I know you have a check earlier so that code will only run if 1000/FPS > SDL_GetTicks() - start. Problem is that SDL_GetTicks() might not return the same value for the two calls as time advances.
Thank you for your response!

For some reason i have never heard or GetKeyState but i will start read about that.

But i have no idea on how to regulate the fps in other ways, how would i do that?
Last edited on
For some reason i have never heard or GetKeyState but i will start read abou that.
The problem with your code was probably that the key array was too small for all of the possible SDLKey values.

But i have no idea on how to regulate the fps in other ways, how would i do that?
Call SDL_GetTicks() once and use the same value in both places. Something like this:
1
2
3
4
5
Uint32 now = SDL_GetTicks();
if(1000/FPS > now - start)
{
	SDL_Delay(1000/FPS - (now - start));
}
Last edited on
Oh, now i get what you mean!

I will dig into some code now, Thank you for the help :)
Topic archived. No new replies allowed.