moving snake with SDL

Hi everyone,

I'm trying to make snake as a way to teach myself SDL. Right now I don't really have a snake yet, I just have a cube that can change direction.
Although it works, it doesn't work in the same way I would want it to work :P
It seems to remember which keys I pressed, for some reason...
The snake makes 4 moves each second, so lets say I press:
RIGHT-LEFT-RIGHT-LEFT-RIGHT in under a fourth of a second, then it will keep changing directions for 1,25 seconds, even if I don't press any key in the next second...
I have no idea why the computer seems to memorize the keys I pressed, and I also have no idea how to solve it...
Any help would be very much appreciated :)

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
int main(int argc, char * args[])
{
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_Surface* screen;
	screen = SDL_SetVideoMode(500,400,32,SDL_SWSURFACE);
	bool running = true;
	const int FPS=4;
	Uint32 start;
	int snakeonoff[20][25] = {0};
	SDL_Rect rect[20][25];
	for (int i = 0; i < 20; i ++) {
		for (int j = 0; j < 25; j++) {
			rect[i][j].x = 20*j;
			rect[i][j].y = 20*i;
			rect[i][j].w = 19;
			rect[i][j].h = 19;
		}
	}
	int snakedirection = 2; // 1: up, 2: right, 3: down, 4: left

	//set colors
	Uint32 black = SDL_MapRGB(screen->format,0000,0000,0000);
	Uint32 white = SDL_MapRGB(screen->format,0xff,0xff,0xff);
	//draw background white
	SDL_Rect background;
	background.x = 0;
	background.y = 0;
	background.w = 500;
	background.h = 400;
	SDL_FillRect(screen,&background,white);


	snakeonoff[1][1] = 1;

	//game loop
	while (running){
		start = SDL_GetTicks();
		SDL_Event event;
		if (SDL_PollEvent(&event)) {
			if (event.type == SDL_KEYDOWN){
				switch( event.key.keysym.sym ) {
					case SDLK_UP:
						snakedirection = 1;
						break;
					case SDLK_RIGHT:
						snakedirection = 2;
						break;
					case SDLK_DOWN:
						snakedirection = 3;
						break;
					case SDLK_LEFT:
						snakedirection = 4;
						break;
				}
			}
		}
		else if( event.type == SDL_QUIT )
            {
                //Quit the program
                running = false;
            }


		//Logic & render
		for (int i = 0; i < 20; i ++) {
			for (int j = 0; j < 25; j++) {
				(snakeonoff[i][j])?SDL_FillRect(screen,&rect[i][j],white):SDL_FillRect(screen,&rect[i][j],black);
			}
		}

		bool movedone = false;
		for (int i = 0; i < 20; i ++) {
			for (int j = 0; j < 25; j++) {
				if (snakeonoff[i][j]&&!movedone){
					snakeonoff[i][j] -= 1;
					(snakedirection%2==0)?snakeonoff[i][j+3-snakedirection]=1:snakeonoff[i-2+snakedirection][j]=1;
					movedone = true;
				}
			}
		}

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

I don't know about SDL, but something doesn't seem right about your delay @line 83:
if (250 > time played)

Maybe it should be something like:
1
2
3
4
currentTick = getTicks();
if (currentTick - lastTick < FPS)  //  If it has been less than FPS ticks
  wait(FPS - (currentTick - lastTick);  // wait that difference
lastTick = currentTick;


With that in mind, I would suspect that you could move the logic to only occur FPS times:
1
2
3
4
5
6
currentTick = getTicks();
if (currentTick - lastTick < FPS)  //  If it has been less than FPS ticks
  wait(FPS - (currentTick - lastTick);  // wait that difference
else
  /* do logic */; 
lastTick = getTicks();


To get to your problem, you are sending messages faster than the screen is updated. I don't know exactly how you would solve this, but at least an idea:

~Poll Event must remove the event from the list, right?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
if (SDL_PollEvent(&event) && acceptCommand) {
  if (event.type == SDL_KEYDOWN){
    switch( event.key.keysym.sym ) {
    case SDLK_UP:
      snakedirection = 1;
      acceptCommand = false;
      break;
    //...

//...

currentTick = getTicks();
if (currentTick - lastTick < FPS)  //  If it has been less than FPS ticks
  wait(FPS - (currentTick - lastTick);  // wait that difference
else
  acceptCommand = true; 
lastTick = getTicks();




Last edited on
Topic archived. No new replies allowed.