Structure of classes in good Game Engine?

Started by
45 comments, last by Cygon 11 years, 9 months ago
Hello everyone :)

Well I'm making a game with a friend, and we're having small problem with organizing our classes.
What we're doing is having main engine class, which creates all classes we use in it, then we pass the
classes into constructor that we want to use.. eg:
[source lang="cpp"]gameWorld = new ChunkManager(LogSys, gfxSystem);
gameCamera = new Camera(ScreenWidth, ScreenHeight, 0.0f, 0.0f, 0.0f, SDL_Key, events,joystick1, LogSys);
Time = new GlobalTime(LogSys);
Menu = new SDL_Menu(this,gameCamera,events,Time,LogSys);[/source]
The thing is, we pretty much pass in LogSys class to EVERYTHING!
Is there any easier way to distribute it to pretty much everything?
I was thinking of inheriting it to everything, but i heard inheritance is bad in some cases to game engines..?


Well thanks for help in advance, cant wait to see the answers! :)
Advertisement
If it's used everywhere, make it global. Some people fight to the death to ensure there are no globals in the code... but sometimes, globals are necessary, and it keeps the code interface nice and tidy. (Don't use globals everywhere though, since they can be a pain to track when debugging)

Using inheritance isn't "bad" all of the time, only when it's abused, like any other tool.
At the moment, try focusing on implementing the game, and think less about the engine. You'll learn a lot about what you really need the engine to do from making a game.

Hope this helps :)

Saving the world, one semi-colon at a time.

I'm one of those people who fight to death not to have any globals in code :) is there any other way? :)
Inheritance is not bad. It can be bad if you do it wrong or too much. Inheritance is very good when you want substitutable behavior. Take a look at the C++ Faq on inheritance:

http://www.parashift.com/c++-faq-lite/proper-inheritance.html

On your LogSys case, I would go for a global as MajorTom suggested. Take a look at your sentence "[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]Is there any easier way to distribute it to pretty much everything?"

well, globals are for eveything everywhere.[/background]

[/font]
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.
Keep in mind that your logging system probably doesn't need to be a class at all. Consider using a simple free function instead, possibly in a namespace.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Debug utilities (ie logging) is one of the very few things which I consider suitable for global access (ie global variable, global function, singleton, ..). If you have other stuff you need everywhere, that might indicate a code design/architecture problem.
Personally I wouldn't bother with either.

There are already a bajillion existing logger systems out there, most are far more comprehensive than an individual would ever use. The better systems integrate with your debugger, allow multiple simultaneous output methods including logging across networks, provide graphical visualizations when comparing bulk logs, and do much more than simply output individual text blobs.

Why re-invent the wheel?

Keep in mind that your logging system probably doesn't need to be a class at all. Consider using a simple free function instead, possibly in a namespace.


This.

If you still decide it needs to be a class, ask yourself: does it need to be instantiated? What benefit do I get for having two or more instances of logger class? If there's none, then you don't need a class.
You can do something like this


class Log {
public:
static Log* Get() {
if( !m_pInstance )
m_pInstance = this;
return m_pInstance;
}
protected:
Log* m_pInstance;
};

Then use the log like this within your classes
Log* pLog = Log::Get();
pLog->Write( "Me and the Cap't make it happen!" );

Brendon Glanzer


You can do something like this


class Log {
public:
static Log* Get() {
if( !m_pInstance )
m_pInstance = this;
return m_pInstance;
}
protected:
Log* m_pInstance;
};

Then use the log like this within your classes
Log* pLog = Log::Get();
pLog->Write( "Me and the Cap't make it happen!" );




This is the "singleton pattern" or as I like to refer to it "the greatest sin perpetuated by programmers with good intentions."

The singleton thing has been debated to death, so if you're interested, I invite you to go search around for any of the dozens of threads on the subject. For now, though, I will leave it at this: please, don't use that code. Ever.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement