Pacman: Exception with my Map object's Sprite object

Started by
3 comments, last by Sean_Seanston 16 years, 1 month ago
Just a small question here but with a lot of code since it kind of deals with some of the finer details of objects within objects etc... I'm making Pacman. I have a class to represent my map and a Sprite class which is used to handle every individual picture of every object in the game. Here's my Map class in map.h:
#ifndef MAP_H
#define MAP_H

#include "sprite.h"

class Map
{
private:
	static const int MAPTILES_X = 29;
	static const int MAPTILES_Y = 32;

	Sprite spr;
	
	static enum Tiles
	{
		PASSABLE,
		IMPASSABLE,
	};

	Tiles MapTiles [MAPTILES_X][MAPTILES_Y];

public:
	Map();
	~Map();
};

extern Map gameMap;

#endif
Here's map.cpp:
#include "map.h"

Map gameMap;

Map::Map()
{
	spr.init("pacmap.png");
}

Map::~Map()
{
	spr.free();
}
The init function is just a member of the Sprite class used to load in the appropriate image for a Sprite. I don't think there's any point showing it here, it's basically just the typical SDL image loading function where we convert the image to SDL display format etc. The problem is that I get an exception with this code when using spr.init(); It occurs with SDL_Surface* temp found inside the init() function. Basically, it seems pretty obvious that the Sprite object inside the Map object isn't being initialized properly and the init() function is looking for something that doesn't exist or isn't set up like it should be since temp is all full of "Cannot be Evaluated" in the debug output. I figure I could just call gameMap.spr.init("pacmap.png"); as soon as it's required by the game,i.e. right before gameplay begins but that seems rather sloppy and besides, it's better that I learn what's going wrong here anyway. Should I perhaps use a Sprite* instead of a Sprite inside the Map class? When using pointers the problem seems to disappear; I have a pointer that creates a new Menu gamestate which uses the same idea as my Map class but that works perfectly. Also, simply changing
extern Map gameMap
Map gameMap
to
extern Map* gameMap
Map* gameMap
appears to fix the problem. Where's the problem here? Should I always use pointers in situations like this or is there a simpler way of fixing it that I've overlooked? I haven't really been coding for a few weeks so I'm probably a bit rusty by now anyway. Thanks for bearing with me if you've read this far :D
Advertisement
Did you make sure SDL_Init is called before Sprite::init?
It seems like you have a Sprite object inside a Map object that is declared globally, and global variables is created before main gets executed.

Map* gameMap;int main(){  SDL_Init(...):   gameMap = new Map(); // OK. SDL is initialized so creating a sprite is ok  ...}


Map gameMap; // Error. SDL is not initialized at this point so creating the sprite failsint main(){  SDL_Init(...):   ...}


Make sure SDL_Init is called before any other SDL functions (like the ones inside Sprite::init) and see if that helps
Hmm... cool, I put

SDL_Init( SDL_INIT_EVERYTHING );

into the Map constructor just as a test and it worked fine that way. Thanks :p

Obviously I'll need to figure out another way to do it properly though, so is this situation best dealt with using pointers?

I imagine I could also put "Map gameMap" after SDL_Init() in the main() function but that's probably an inelegant way to do it...

EDIT: Would it be a good idea to declare gameMap as a static member of the class that represents the gameplay gamestate maybe?

[Edited by - Sean_Seanston on March 2, 2008 2:48:06 PM]
Quote:Original post by Sean_Seanston
Hmm... cool, I put

SDL_Init( SDL_INIT_EVERYTHING );

into the Map constructor just as a test and it worked fine that way. Thanks :p

Obviously I'll need to figure out another way to do it properly though, so is this situation best dealt with using pointers?

Not necessarily. Even if using a pointer may be a fine choice you shouldn't feel obligated.

One way could be to give the Map class a init function and create the sprite in there.
class Map{  void init()  {    spr.init();  }  ...};int main(){  SDL_Init(...);  gameMap.init();  ...}

That way you can keep the global gameMap object as it is.
Quote:
I imagine I could also put "Map gameMap" after SDL_Init() in the main() function but that's probably an inelegant way to do it...

I wouldn't say that. Its a viable option IMO. That way you get rid of the global aspect of the gameMap which is considered a good thing by many.
Quote:
EDIT: Would it be a good idea to declare gameMap as a static member of the class that represents the gameplay gamestate maybe?

And make sure SDL is initialized in the gameplay object before gameplay creates the gameMap? I guess that should work even though it doesn't really solve the problem, it just moves it around.


[Edited by - pulpfist on March 2, 2008 4:40:56 PM]
Cool, I seem to have got things working ok.

I ran into some problems with a corrupted heap though for ages... turned out I was trying to call SDL_FreeSurface on the same surface twice through both the Sprite destructor and the destructor of what held the Sprite ;O

This topic is closed to new replies.

Advertisement