Page 1 of 2
Question on game structure?
Posted: Thu Dec 30, 2010 3:17 pm
by StoveBacon
I'm working on my first big game, and I have a question on how I can give multiple classes access to a single class.
I want to make an image manager class but I can't see how each thing that has its own image would have access to this class.
like, is there a way to get all the classes I need to be able to access one class so I don't have to have every class creating an image manager?
Re: Question on game structure?
Posted: Thu Dec 30, 2010 4:53 pm
by ismetteren
Just pass each class that should have access to the image manager a pointer to it(an instance of it).
No reason to use the singleton pattern...
Re: Question on game structure?
Posted: Thu Dec 30, 2010 6:29 pm
by StoveBacon
Were would I pass the pointer from?
Edit: ALSO how can i do something like have an input class go to my game system class in case I want to toggle full screen but my buffer is in my image manager, neither of witch have any connection with each other?
Re: Question on game structure?
Posted: Fri Dec 31, 2010 6:38 am
by ismetteren
KeithStoffel wrote:Were would I pass the pointer from?
Edit: ALSO how can i do something like have an input class go to my game system class in case I want to toggle full screen but my buffer is in my image manager, neither of witch have any connection with each other?
I think we need to know more about how your game is designed.
I see many people who have the game logic and rendering situated within the entities/game objects, so each entity gets a update() call and a render() call each frame. I don't do it that way, instead my game objects are only data. The logic and rendering is then handled in "sub-systems". Every subsystem has pointers to the entities(Actually not really the entities themselves, but one of their components, see the topic about component based entities. Also they don't need to have pointers to every entity, some has maybe just to one or a few, could be an AI system) and gets called each frame to do what they do(AI, logic, physics, rendering, collision detection and so on).
The sub-systems communicate with each other using an event system. Each one of them has a pointer to the event system, and the event system has a pointer to each of them. When an event happens the event system calls all the subsystems, and they can respond to it. The subsystems can also trigger events, using their pointer to the event system. They get the pointer to the event system in the constructor.
I'm not saying that that is the best way at all, it's just the way i prefer at the moment, also it is not a complete description at all. I am not saying that you should change the whole structure of your game, I was just showing a way to do things. If you gave a similar description of your structure it might be easier to help. The question "Were would I pass the pointer from?" is hard to answer when i have no idea what options you have, and the other question is hard to answer since i have no idea what your game system class is doing, i only know that you input class probably have something to do with the user input, i have no idea how it communicates that input to the rest of the game, and what parts of the game it communicates it to. I guess the image manager is one of those you see in many tutorials that store all the images in a map and returns them when you call getImage("identifier string") on it. But i can only guess.
Re: Question on game structure?
Posted: Fri Dec 31, 2010 10:44 am
by StoveBacon
http://img513.imageshack.us/i/classstruct.png/
So i have a base object class that has x,y,w,h and other basic stuff. Most things that have sprites will inherit this class. The player and enemy do.
I Want to have the baseObject class have access to the image manager so at anytime any inherited class can create an image in the image manager
Re: Question on game structure?
Posted: Fri Dec 31, 2010 11:17 am
by GroundUpEngine
*couch* Singletons suck *cough*
KeithStoffel wrote:http://img513.imageshack.us/i/classstruct.png/
So i have a base object class that has x,y,w,h and other basic stuff. Most things that have sprites will inherit this class. The player and enemy do.
I Want to have the baseObject class have access to the image manager so at anytime any inherited class can create an image in the image manager
Good start i think. Infact quite similar to what i usually do!
Re: Question on game structure?
Posted: Fri Dec 31, 2010 1:44 pm
by StoveBacon
Can someone tell me the best way to get the pointer of the imageManager to my base object? and were should i create the imageManager?
Re: Question on game structure?
Posted: Fri Dec 31, 2010 2:05 pm
by Ginto8
N64vSNES, stop bitching. They (and many others) have given plenty of reasons why you SHOULDN'T use singletons.
GyroVorbis and Arce, although I understand your outrage, don't hijack this guy's thread. He just wants some decent advice, which everyone seems unwilling to give, unless the advice is "don't use singletons."
KeithStoffel wrote:Can someone tell me the best way to get the pointer of the imageManager to my base object? and were should i create the imageManager?
OK, ImageManager should probably be created somewhere in the beginning of your main() function. Here is a sample implementation of how to give access:
Code: Select all
struct ImageObject {
// image manager used for image handling
ImageManager* Mgr;
ImageObject(ImageManager& mgr) : Mgr(&mgr) {}
};
Each class that requires image use should inherit from this, and should be passed an ImageManager instance at construction. I left Mgr public in case you want to hotswap ImageManagers in order to change the functionality of the object after construction.
Keep in mind that this is just a sample of how you could do it; the actual implementation is up to you, and the best choice of how to implement it depends a lot on your ImageManager and how it should be used.
Re: Question on game structure?
Posted: Fri Dec 31, 2010 2:23 pm
by StoveBacon
Code: Select all
struct ImageObject {
// image manager used for image handling
ImageManager* Mgr;
ImageObject(ImageManager& mgr) : Mgr(&mgr) {}
};
Wouldn't that make a new image manager for every class that inherits it then?
Re: Question on game structure?
Posted: Fri Dec 31, 2010 3:06 pm
by GroundUpEngine
KeithStoffel wrote:Code: Select all
struct ImageObject {
// image manager used for image handling
ImageManager* Mgr;
ImageObject(ImageManager& mgr) : Mgr(&mgr) {}
};
Wouldn't that make a new image manager for every class that inherits it then?
Nop. Its just a reference to the original 'ImageManager' instance in the main() function, which is passed to an 'ImageObject' on constuction
Re: Question on game structure?
Posted: Fri Dec 31, 2010 3:15 pm
by StoveBacon
ImageManager* Mgr;
i'm confused, wouldn't that create an imageManager?
Re: Question on game structure?
Posted: Fri Dec 31, 2010 3:16 pm
by dandymcgee
KeithStoffel, I would like to apologize on behalf of the community for the complete derailing of your perfectly legitimate question.
I've moved the flame war to Posts You Shouldn't Make. Please keep this thread on topic from here on out.
KeithStoffel wrote:ImageManager* Mgr;
i'm confused, wouldn't that create an imageManager?
Nope, that declares a pointer to an object of type ImageManager.
Re: Question on game structure?
Posted: Fri Dec 31, 2010 3:20 pm
by StoveBacon
I'm still confused on how this is implemented.
Re: Question on game structure?
Posted: Fri Dec 31, 2010 3:59 pm
by short
KeithStoffel wrote:Can someone tell me the best way to get the pointer of the imageManager to my base object? and were should i create the imageManager?
KeithStoffel wrote:I'm still confused on how this is implemented.
Definitely create your imageManager before you create your derived class. Do something like this:
Code: Select all
class imageManager; // forward declaration, I didn't bother to implement for this example
class baseclass
{
private:
baseclass(); // notice
imageManager* pImgMgr; // you could use references instead of pointers if you have
// an implementaiton of imageManager
public:
explicit baseclass(imageManager* pIM);
imageManager* getImgHandle();
};
baseclass::baseclass(imageManager* pIM)
{
pImgMgr = pIM;
}
/* be careful with returning handles to internal objects. In this instance should be OK since
pImgMgr just points to another object.*/
imageManager* baseclass::getImgHandle()
{
return pImgMgr;
}
Code: Select all
class derivedclass : public baseclass
{
public:
explicit derivedclass(imageManager* pIM);
};
/* note: since baseclass default constructor is private, you must call the other
constructor (with required parameter) like this:
*/
derivedclass::derivedclass(imageManager* pIM) : baseclass(pIM)
{
}
Code: Select all
int main(int argc, char* args[])
{
imageManager* img = new ImageManager();
derivedclass* d = new derivedclass(img);
d->getImgHandle()->doSomething();
return 0;
}
Your derived class, or base class if you want to instantiate one ( baseclass* b = new baseclass(img) ), all now can talk to your imagemanager.
note: I did all this in one file, noticing the lack of includes among the different classes/main function.
Is this what you wanted?
Re: Question on game structure?
Posted: Fri Dec 31, 2010 9:01 pm
by Ginto8
I have a few things to say about short's code:
1, I don't like explicit constructors, they make initialization of objects more obtuse and ugly.
2, the ENTIRE POINT of using a base class is to allow derived classes to use the ImageManager, not to allow the rest of the program to go hog wild with each reference to an ImageManager, so the getImgHandle function is unnecessary and doesn't allow hotswapping (the entire reason my example was a struct not a class).
3, Like I said before, the DERIVED CLASS is supposed to be the one messing with the ImageManager, not main(). All external functions should
really do with the ImageManager reference is change it for hotswapping. If they want to do anything else, don't do it through the derived class's reference.
4, when I say "reference", I mean pointer. References don't allow you to change where they point, thus completely disallowing the hotswapping flexibility that was part of my goal in that implementation.
I must admit however, that the ImageManager reference should be encapsulated in the base class so that other bits of code can't fuck with it. And that's what my example code will do.
So, all in all, here is how I'd implement it:
The base:
Code: Select all
class ImageBase {
ImageManager* mgr;
public:
ImageBase(ImageManager& Mgr) : mgr(&Mgr) {}
void swapMgr(ImageManager& Mgr) { mgr = &Mgr; }
};
The Derived:
Code: Select all
class ImageDerived : public ImageBase {
// class stuff
public:
// public class stuff
ImageDerived(ImageManager& Mgr /* derived class initialization parameters go here */) :
ImageBase(Mgr) /* other constructions */ { /* constructor stuff */ }
};
The use:
Code: Select all
ImageManager mgr(/* image manager initialization parameters */);
ImageDerived derived(mgr /* other parameters */);
// do stuff with derived