SDL - Renderer doesn't updates.

Hello people from CPP. First post. Well, I'm in an awkward situation with my code, because it compiles, but doesn't works properly and doesn't returns any errors.
I've been sitting here for 8 hours debugging it because all the time it never returned errors, however eventually they appeared and were just logical flaws.
The error is: The renderer draws what appears first, but doesn't updates it even though it's inside the Main Game Loop. Here are the codes that will be useful:

main.cpp
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
#include "stdafx.h"
#include "SDL.h"
#include "Food.h"
#include "serpiente.h"

const int GAME_SPEED = 50; //px por tick de juego.

//WINDOW START
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Event evnt;
//WINDOW END

void init() {
	SDL_Init(SDL_INIT_VIDEO);
	window = SDL_CreateWindow("Snake", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
	SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
	SDL_RenderClear(renderer);
}

void close() {
	SDL_DestroyWindow(window);
	window = NULL;
	SDL_Quit();
}

int main(int argc, char *argv[]){
	init();
	bool quit = false;
	serpiente snake(renderer);
	Food food;
	
	while (!quit) {
		while (SDL_PollEvent(&evnt) != 0) {
			if (evnt.type == SDL_QUIT) {
				quit = true;
			}
		}
		SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
		SDL_RenderClear(renderer);
		snake.m_update(renderer);
		food.m_update(renderer);
		snake.foodCollision(snake, food);
		snake.wallCollision(snake);
		snake.selfCollision(snake);
		SDL_RenderPresent(renderer);
		SDL_Delay(GAME_SPEED);
	}
	close();
	return 0;
}


serpiente.cpp

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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "stdafx.h"
#include "serpiente.h"
#include "SDL.h"

serpiente::serpiente(SDL_Renderer *renderer) : m_currentDirection(RIGHT),	m_size(0){
	for (int i = 0; i < INITIAL_SNAKE_SIZE; ++i)
		m_appendSegment();
	m_update(renderer);
}


serpiente::~serpiente(){

}

int serpiente::m_getHeadX() {
	return m_snake.back().space.x;
}

int serpiente::m_getHeadY() {
	return m_snake.back().space.y;
}


void serpiente::m_appendSegment(){
	++m_size;
	Segment segment;
	
	if (m_snake.empty()) {
		segment.space.x = SCREEN_WIDTH / 2;
		segment.space.y = SCREEN_HEIGHT / 2;
		segment.space.w = SNAKE_SEGMENT_SIZE;
		segment.space.h = SNAKE_SEGMENT_SIZE;
		segment.direction = m_currentDirection;
	}
	else {
		//Nunca le pongan a un objecto el mismo nombre que la clase, pues cuando quieran hacer otro objeto de la misma clase lo va a tomar como objeto el nombre.
		Segment lastSegment = m_snake.back();
		switch (lastSegment.direction) {
		case RIGHT:
			segment.space.x = lastSegment.space.x + SNAKE_SEGMENT_SIZE;
			segment.space.y = lastSegment.space.y;
			break;
		case LEFT:
			segment.space.x = lastSegment.space.x - SNAKE_SEGMENT_SIZE;
			segment.space.y = lastSegment.space.y;
			break;
		case DOWN:
			segment.space.x = lastSegment.space.x;
			segment.space.y = lastSegment.space.y + SNAKE_SEGMENT_SIZE;
			break;
		case UP:
			segment.space.x = lastSegment.space.x;
			segment.space.y = lastSegment.space.y - SNAKE_SEGMENT_SIZE;
			break;
		}
		segment.space.w = SNAKE_SEGMENT_SIZE;
		segment.space.h = SNAKE_SEGMENT_SIZE;
		segment.direction = m_currentDirection;
	}
	m_snake.push_back(segment);
}

void serpiente::m_addSpot(){
	Spot spot;
	Segment segment = m_snake.back();
	spot.m_x = segment.space.x;
	spot.m_y = segment.space.y;
	spot.m_direction = m_currentDirection;
	spot.m_counter = m_size;
	m_spot.push_back(spot);
}

void serpiente::m_move(){
	for (Spot &spot : m_spot) {
		for (Segment &segment : m_snake) {
			if (spot.m_x == segment.space.x && spot.m_y == segment.space.y && spot.m_counter > 0) {
				segment.direction = spot.m_direction;
				--spot.m_counter;
			}
		}
	}
	for (Segment &s : m_snake) {
		switch (s.direction) {
		case RIGHT:
			s.space.x += SNAKE_SEGMENT_SIZE;
		case LEFT:
			s.space.x -= SNAKE_SEGMENT_SIZE;
		case DOWN:
			s.space.y += SNAKE_SEGMENT_SIZE;
		case UP:
			s.space.y -= SNAKE_SEGMENT_SIZE;
		}
	}
}

void serpiente::m_draw(SDL_Renderer *renderer) {
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	for (Segment s : m_snake) {
		SDL_RenderFillRect(renderer, &(s.space));
	}
}

void serpiente::m_update(SDL_Renderer *renderer){
	if (event.type == SDL_KEYDOWN) {
		switch (event.key.keysym.sym) {
		case SDLK_RIGHT:
			m_currentDirection = m_currentDirection != LEFT ? RIGHT : LEFT; break;
		case SDLK_LEFT:
			m_currentDirection = m_currentDirection != RIGHT ? LEFT : RIGHT; break;
		case SDLK_UP:
			m_currentDirection = m_currentDirection != DOWN ? UP : DOWN; break;
		case SDLK_DOWN:
			m_currentDirection = m_currentDirection != UP ? DOWN : UP; break;
		}
		m_addSpot();
		}
	m_move();
	m_draw(renderer);
}

void serpiente::foodCollision(serpiente &snake, Food &food){
	int x_snake = snake.m_getHeadX();
	int y_snake = snake.m_getHeadY();
	int x_food = food.m_getX();
	int y_food = food.m_getY();
	if (x_snake == x_food && y_snake == y_food) {
		snake.m_appendSegment();
		food.m_generate();
	}
}

void serpiente::wallCollision(serpiente &snake){
	if (snake.m_getHeadX() > SCREEN_WIDTH || snake.m_getHeadX() < 0
		|| snake.m_getHeadY() > SCREEN_HEIGHT || snake.m_getHeadY() < 0) {
		exit(-1);
	}
}

void serpiente::selfCollision(serpiente &snake){
	for (int i = 0; i < m_snake.size() - 1; i++) {
		if (snake.m_getHeadX() == m_snake.at(i).space.x && snake.m_getHeadY() == m_snake.at(i).space.y) {
			exit(-1);
		}
	}
}


Why the renderer isn't updating? Sorry if the code doesn't appears formatted, I'm new here and the Format options don't seem to be working.
Last edited on
I think you may not be using SDL_PollEvent correctly. Try something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
	while (true) {
		if (SDL_PollEvent(&evnt) != 0 && evnt.type == SDL_QUIT)
			break;
		SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
		SDL_RenderClear(renderer);
		snake.m_update(renderer);
		food.m_update(renderer);
		snake.foodCollision(snake, food);
		snake.wallCollision(snake);
		snake.selfCollision(snake);
		SDL_RenderPresent(renderer);
		SDL_Delay(GAME_SPEED);
	}

Last edited on
The use of SDL_PollEvent looks fine, if all you want to do is check for SDL_QUIT events that is.

I think the problem is that nothing in your game gets updated. In serpiente::m_update() you use a SDL_Event variable named event but it doesn't look like you update this variable anywhere. Even if it is updated when evnt in main.cpp is updated it would still not work correctly. I'm not sure if SDL_PollEvent overwrites the event or leaves it as is when there are no more events, but it could still fail to work correctly if more than one event happen and the SDL_KEYDOWN event is not the most recent one.

If you want to react on an event you should do so inside the SDL_PollEvent loop. You should probably not move the object from inside here, only update the direction.

Another alternative is to use SDL_GetKeyboardState() (https://wiki.libsdl.org/SDL_GetKeyboardState) which allows you to check the status of each individual key. You can do this from anywhere, not just from inside the event loop. This is usually suitable for things like movement where holding a key does the same thing each frame for as long as the key is hold down, but if you want to do something special when a key is pressed, e.g. initiate a jump or fire a bullet, you probably want to do that inside the event loop.
Last edited on
Topic archived. No new replies allowed.