SDL problem!

Hello. I have a big problem! I am making a "game" in SDL and the until i created a player object class in game class constructor everything worked just fine. The weirdest of all is that the screen changes from fullscreen to none fullscreen all the time. Like if someone repeating press f5. The player class shouldnt have any effect on the key array.

Excuse my bad english, Here comes the code.

Im sorry but it felt like i couldnt cut on the code since the problem could be anywhere.

(the main function just create a game object. Felt uneccessary to post)

Thanks in advance!


here is base.h

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
#ifndef BASE_H
#define BASE_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

using namespace std;

class base
{
public:
	static const int SCREEN_WIDTH = 800;
	static const int SCREEN_HEIGHT = 600;
	static const int SCREEN_BPP = 32;
	static const int FPS = 60;
	
	static const int Gravity = 2;
	static const int vel = 2;
	static const int TILE_SIZE = 50;
	static SDL_Rect coord;
	base(void);
	SDL_Surface * Load_Image(string filename);
	bool CheckCollision(SDL_Rect r1,SDL_Rect r2);
	~base(void);
};

#endif 


here is base.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
#include "base.h"


base::base(void)
{
}

SDL_Surface * base::Load_Image(string filename)
{
	SDL_Surface * IMG = IMG_Load(filename.c_str());
	if(IMG != NULL)
	{
		SDL_Surface * Opt = SDL_DisplayFormat(IMG);
		SDL_FreeSurface(IMG);
		cout << "Loading image " << filename << " Succeeded!" << endl;
		return Opt;
	}else{
		cout << "Error: image " << filename << " could not be loaded" << endl;
		return NULL;
	}
}

bool base::CheckCollision(SDL_Rect r1,SDL_Rect r2)
{
	if(r1.x > r2.x+r2.w){
		return false;
	}
	else if(r1.y > r2.y+r2.h){
		return false;
	}
	else if(r1.x+r1.w < r2.x){
		return false;
	}
	else if(r1.y+r1.h < r1.y){
		return false;
	}else{
		return true;
	}
}

base::~base(void)
{
}


Here is game.h

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
#include "base.h"
#include "player.h"

#ifndef GAME_H
#define GAME_H

class game : public base
{
public:
	game(void);
	~game(void);
private:
	bool InitSDL();

	void GameLoop();
	void HandleEvents();
	void UpdateGame();
	void Render();

	void LoadMap(string filename);
	void BlitMap();

	bool running;
	bool fullscreen;
	SDL_Event event;
	bool keys[272];

	player * Player;
	SDL_Surface * screen,*Background,*Blocks;
	SDL_Rect BackgroundBox;
	vector< vector<int> > map;
};

#endif 


here is game.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "game.h"

SDL_Rect base::coord;

game::game(void)
{
	if(!this->InitSDL()){exit(1);}

	BackgroundBox.x = BackgroundBox.y = coord.x = coord.y = 0;
	coord.w = BackgroundBox.w = 800;
	coord.h = BackgroundBox.h = 600;
	fullscreen = false;
	Background = Load_Image("Background.png");
	Blocks = Load_Image("Blocks.png");
	this->LoadMap("test.TILEMAP");
	Player = new player;
	this->GameLoop();
}

void game::GameLoop()
{
	Uint32 start, end;

	running = true;
	while(running)
	{
		start = SDL_GetTicks();
		this->HandleEvents();

		this->UpdateGame();

		this->Render();
		end = SDL_GetTicks();
		if(1000/FPS > end - start)
		{
			SDL_Delay(1000/FPS - (end - start));
		}
	}
}

void game::HandleEvents()
{
	while(SDL_PollEvent(&event))
	{
		switch(event.type)
		{
		case SDL_QUIT:
			running = false;
			break;
		case SDL_KEYDOWN:
			keys[event.key.keysym.sym] = true;
			break;
		case SDL_KEYUP:
			keys[event.key.keysym.sym] = false;
			break;
		}
	}
}

void game::UpdateGame()
{
	if(keys[SDLK_a]){
		coord.x-=vel;
		BackgroundBox.x-=vel;
		Player->left();
		if(BackgroundBox.x <= 0)
		{
			BackgroundBox.x = Background->w - SCREEN_WIDTH;
		}
	}
	else if(keys[SDLK_d]){
		coord.x+=vel;
		BackgroundBox.x+=vel;
		Player->right();
		if(BackgroundBox.x >= Background->w - SCREEN_WIDTH)
		{
			BackgroundBox.x = 0;
		}
	}		
	else if(keys[SDLK_ESCAPE]){
		running = false;
	}else if(keys[SDLK_F5]){
		fullscreen = (!fullscreen);
		if(fullscreen)
		{
			screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);
		}else{
			screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF);
		}
	}

	
}

void game::Render()
{
	SDL_BlitSurface(Background,&BackgroundBox,screen,NULL);
	this->BlitMap();
	Player->blit();
	SDL_Flip(screen);
}

void game::LoadMap(string filename)
{
	ifstream in(filename.c_str());
	int Width,Height,current;
	in >> Width >> Height;

	if(!in.is_open())
	{
		cout << "Error: could not load "<< filename << endl;
		return;
	}

	for(int j = 0;j != Height;j++)
	{
		vector<int> TempVec;
		for(int k = 0; k != Width;k++)
		{
			if(in.eof())
			{
				cout << "Error: File end reached to early" << endl;
				return;
			}
			in >> current;
			TempVec.push_back(current);
		}
		map.push_back(TempVec);
	}
	in.close();
}

void game::BlitMap()
{
	for(int j = 0; j != map.size();j++)
	{
		for(int k = 0; k != map[j].size();k++)
		{
			SDL_Rect BlockRect = {(map[j][k]-1)*TILE_SIZE,0,TILE_SIZE,TILE_SIZE};
			SDL_Rect DestRect = {k * TILE_SIZE - coord.x,j*TILE_SIZE,TILE_SIZE,TILE_SIZE};
			SDL_BlitSurface(Blocks,&BlockRect,screen,&DestRect);
		}
	}
}

game::~game(void)
{
	delete Player;
	SDL_FreeSurface(Blocks);
	SDL_FreeSurface(Background);
	SDL_Quit();
}

bool game::InitSDL()
{
	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
		cout << "Error: could not initialize SDL" << endl;
		return false;
	}else{
		cout << "SDL initialized!" << endl;
	}

	screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF);
	if(screen == NULL)
	{
		cout << "Error: could not initialize the screen" << endl;
		return false;
	}else{
		cout << "screen initialized!" << endl;
	}

	if(TTF_Init() == -1)
	{
		cout << "Error: could not initialize TTF" << endl;
		return false;
	}else{
		cout << "TTF initialized" << endl;
	}

	SDL_WM_SetCaption("SpaceVikings",NULL);

	for(int i = 0; i != 400; i++)
	{
		keys[i] = false;
	}

	return true;
}


here is player.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "base.h"

#ifndef PLAYER_H
#define PLAYER_H

class player : public base
{
public:
	player(void);
	void up();
	void down();
	void left();
	void right();
	void blit();
	void shoot();
	~player(void);
private:
	SDL_Surface * image;
	SDL_Rect box;
	
};

#endif 


here is player.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
#include "player.h"


player::player(void)
{
	image = Load_Image("Player.png");
	box.x = SCREEN_WIDTH/2 - box.w/2;
	box.y = SCREEN_HEIGHT/4;
}

void player::up()
{
	box.y-=vel;
}

void player::down()
{
	box.y+=vel;
}

void player::right()
{
	box.x+=vel;
}

void player::left()
{
	box.x-=vel;
}

void player::blit()
{
	SDL_BlitSurface(image,NULL,SDL_GetVideoSurface(),&box);
}

void player::shoot()
{

}

player::~player(void)
{
}
Last edited on
You should listen to what I have told you in earlier threads. The keys array is too small. If the user press F5, one of the arrow keys or any other key that has a higher key value than 271 you will access elements out bounds in the keys array on line 51 and 54 in game.cpp. This might overwrite memory used by other parts of your program so things might start acting strange.
I have read on other threads about GetKetState and many people says it can be inaccurate when its gonna read fast keypresses. But thank you anyway. But could you please tell me, Why did everything worked fine until i added a player?
Yes GetKetState can be inaccurate but so can your approach too. If the user press a key and release it fast enough so that you get both the SDL_KEYDOWN and the SDL_KEYUP event in the same call to HandleEvents you will never notice that the key was pressed.

If you want to know when a key is pressed you should handle it inside the event loop when you receive the SDL_KEYDOWN event. GetKetState (and your approach) is only useful to know if the key is hold down at this moment.

You should definitely handle the F5 key inside the event loop otherwise the screen will change between fullscreen and window mode like crazy as long as the user holds down the F5 key.

I don't know why it worked before you added a player. It is probably just a consequence of undefined behaviour. SDLK_F5 has value 286 so you should see why the keys array is too small. What you do invokes undefined behavior so anything could happen. This is the first problem you should fix.

Last edited on
Yes GetKetState can be inaccurate but so can your approach too. If the user press a key and release it fast enough so that you get both the SDL_KEYDOWN and the SDL_KEYUP event in the same call to HandleEvents you will never notice that the key was pressed.

If you want to know when a key is pressed you should handle it inside the event loop when you receive the SDL_KEYDOWN event. GetKetState (and your approach) is only useful to know if the key is hold down at this moment.

You should definitely handle the F5 key inside the event loop otherwise the screen will change between fullscreen and window mode like crazy as long as the user holds down the F5 key.

I don't know why it worked before you added a player. It is probably just a consequence of undefined behaviour. SDLK_F5 has value 286 so you should see why the keys array is too small. What you do invokes undefined behavior so anything could happen. This is the first problem you should fix.


The first problem was solved. But i just found out another one. If i increase the players box with the same amount as i move the camera the player move faster than the screen, which i find very weird
Last edited on
Topic archived. No new replies allowed.