Hey guys,
I need a little help on how to go about structuring a new project. I am familiar with how to go about doing things object-oriented, however I don't have much experience with working with libraries/engines.
In a new project I am likely to create classes for my main character and level objects, and I am tempted to define ISceneNodes here so that each object can have it's mesh/texture all set up. But to do this my game objects would have to access parts of the system like the Irrlicht SceneManager which would be in a class much higher up in the hierarchy, and it just seems a bit messy and tightly coupled.
I ask this because when I start including other libraries like a physics engine, audio engine etc. it would be nice to keep everything as loosely coupled as possible so objects only rely on objects lower in the hierarchy and I can avoid problems like having dependancies all over the place.
I'd appreciate if someone can tell me if I'm thinking the right way and assist me with a solution, or feel free to tell me I'm thinking the wrong way! Thanks in advance x
OOP Game Structure [solved]
-
- Posts: 40
- Joined: Mon Sep 11, 2006 1:06 pm
OOP Game Structure [solved]
Last edited by klikmaster on Sun Jun 22, 2008 12:14 am, edited 1 time in total.
~IRRLICHT ROX MY SOX~
Hello,
The way I do it, and I am not sure if it is "correct" is I pass a reference to my Irrlicht Device to the classes that require it (basically all of them). This is in C# but it is easily ported to C++.
Here is an example of a class I would write;
Right before I enter my main rendering loop I would have something like this;
I hope this helps, good luck with your endeavours.
The way I do it, and I am not sure if it is "correct" is I pass a reference to my Irrlicht Device to the classes that require it (basically all of them). This is in C# but it is easily ported to C++.
Here is an example of a class I would write;
Code: Select all
internal class Menu {
IrrlichtDevice _device = null;
internal bool InitializeMenu(IrrlichtDevice device) {
try {
this._device = device;
return true;
} catch { return false;}
}
}
Code: Select all
Menu _menu = new Menu();
if (!_menu.InitializeMenu(_device))//failed to initialize class so shut down
_device.CloseDevice();
while (_device.Run()) {
//...
There are two ways possible basically:
1. declare those Irrlicht classes (device, scene manager, gui environment and so on) global. Like that any part of your code can access them. This works well with simple, short projects.
2. make your class to hold pointer to Irrlicht classes it needs, preferably as private member and pass it in to your class in its constructor. This is prefered for more complicated projects with code split in to lots of files, classes and so on.
Example:
grab() will tell engine that you are using scene manager and prevent it to discarding it while you do so. drop() will tell engine you do not use it anymore so it is safe to remove it if needed.
1. declare those Irrlicht classes (device, scene manager, gui environment and so on) global. Like that any part of your code can access them. This works well with simple, short projects.
2. make your class to hold pointer to Irrlicht classes it needs, preferably as private member and pass it in to your class in its constructor. This is prefered for more complicated projects with code split in to lots of files, classes and so on.
Example:
Code: Select all
class MyClass
{
scene::ISceneManager* Smgr;
public:
MyClass(scene::ISceneManager* smgr)
{
Smgr = smgr;
if(Smgr) Smgr->grab();
}
~MyClass()
{
if(Smgr) Smgr->drop();
}
};
Though it may not be the best way, I intend on writing my own abstract SceneManager and SceneNode classes, that for now will simply wrap around Irrlicht. That will allow me to write my actual game using a generic interface, and if I need to switch to another 3D engine, I only need to write a new set of wrappers, without having to touch any of my game logic.
The idea is that if I need to switch to a different engine, I should only have to write the new wrappers and change a single line of existing code.
The idea is that if I need to switch to a different engine, I should only have to write the new wrappers and change a single line of existing code.
-
- Posts: 31
- Joined: Thu Jun 07, 2007 6:23 pm
- Location: New York
- Contact:
I would take Arras' advice one step further and implement a generic class that keeps track of those pointers.
This is a cleaner way of managing the pointers without having to redeclare them for every new class in your game.
You can use this file as such:
This will pass the passed in pointer to the irrlicht device, to the GameEntity class' constructor that will set up the pointers to the SceneManager, GUIEnvironment, etc.
Hope it helps!
Code: Select all
using namespace irr;
using namespace video;
using namespace core;
using namespace gui;
using namespace scene;
using namespace io;
/*
Base class for all game entities. Game Entities
all use Irrlicht.h and the irr namespace derivations.
Therefore, we include them in one place to keep tidy.
*/
class GameEntity
{
public:
GameEntity (IrrlichtDevice *device)
{
this->device = device;
this->driver = device->getVideoDriver();
this->env = device->getGUIEnvironment();
this->smgr = device->getSceneManager();
}
~GameEntity()
{}
protected:
IrrlichtDevice *device;
IGUIEnvironment *env;
IVideoDriver *driver;
ISceneManager *smgr;
};
You can use this file as such:
Code: Select all
#include "GameEntity.h"
class MyClass : public GameEntity
{
public:
MyClass(IrrlichtDevice *device) : GameEntity(device)
{}
};
Hope it helps!
Computer scientist by day...
http://www.mrjoelkemp.com
http://www.mrjoelkemp.com
-
- Posts: 40
- Joined: Mon Sep 11, 2006 1:06 pm