Game Engine Design w/ Allegro 5

Hi,

I am curious on how to keep something OO in this scenario.

Lets say I have a base class called Base and it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base
{
	public:
		Base();
		virtual ~Base();

	  virtual bool Init();
	  virtual void GameInit();
	  virtual bool CreateEvents();

	  virtual bool Go();

	  void Pause();
	  void Resume();

	  virtual void HandleEvents();
	  virtual void Update();
	  virtual void Draw();

	  virtual void MainLoop();
};


And now lets say I want to add a Node class to keep track of ALL moving objects on the screen (NPCs, bullets, main character).

I could do this:

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
class Base
{
	public:
		Base();
		virtual ~Base();

	  virtual bool Init();
	  virtual void GameInit();
	  virtual bool CreateEvents();

	  virtual bool Go();

	  void Pause();
	  void Resume();

	  virtual void HandleEvents();
	  virtual void Update();
	  virtual void Draw();

	  virtual void MainLoop();
	  virtual class Node
		{
			public:

				Node();
				~Node();

				void nCreate(int type,int x,int y);
				void nDraw();
				void nUpdate();

			private:
				//PC = player controlled
				enum NODE_TYPES
				{
					PC, AI
				};
				float x;
				float y;
				double direction;
				bool live;
				int type;

				//Allegro variables
				ALLEGRO_BITMAP  *skin;
		};
};


Now I couldn't access those functions in, say, Base::Gameinit().

How should I organize this?
closed account (3qX21hU5)
I wouldn't have your Node class inside of the base class. Make it a totally seperate class (Don't even inherit the base class).

Then depending on how you want to structure your game you could either have a container of all active nodes inside of your base class (Though I don't really like this route but it is easiest for little games).

Or you can make a scene graph of nodes, which is where you have one root node that will be in your base class and then that root node has children nodes and them children nodes have children nodes ect. ect.

For example

                            root
                            /  \
                           /    \
                 background      entites
                                 /      \
                                /         \
                              player      enemies
                            /                   \
                         player                  enemy
                         bullet                   bullet


Now that is a very basic scene graph but it shows the idea behind it. The main point is your Nodes shouldn't have any relation with your base class. Also make sure to separate specific functionality into classes. By that I mean your classes should be in charge of one thing only.

Anyways good luck and if you didn't understand something I said or more then likely I said it in a way that is hard to understand feel free to ask again and I would be more then willing to explain it in more depth.
Last edited on
Thanks for the response.

Can you explain more on how I would use the one root node class in the base class. I have the syntax and could understand it,I'm missing the concept.
closed account (3qX21hU5)
I am sure there are a bunch of tutorials online that explain Scene Graphs in much more detail then I could here so it would probably be better to check them out instead. Here is some links explaining them

http://en.wikipedia.org/wiki/Scene_graph

http://scriptionary.com/2009/02/17/simple-scene-graph-in-c/


Also here is some basic code for a Scene Graph (Only going to post the headers since it is quite long). Also it uses SFML but I am sure most things can be transferred to allegro easily (Though I am not familiar with Allegro).

SceneNode - This will be the base class for all entities in the game. It defines basic functionality for a scene graph and things common between all entities. The derived classes will then implement their own functionality.

Now this has some extra's in it but the main things are this

1) Being able to attach (When you fire a bullet or something) children to a SceneNode and detach them (Like when something is destroyed)

2) Have a way to update all the SceneNodes in the the Scene Graph. I do it by each scene node having a update function which calls the update function of all its children to.

3) Being able to draw each scene node if it needs to be drawn. Same implementation basically as the update function.

4) Each scene node needs to know who its parent node is and who it's children are.

That is basically it (I might have missed something) and of course you can add extra's on there to.

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
class SceneNode : public sf::Transformable, public sf::Drawable,
                  private sf::NonCopyable
{
    public:
        typedef	std::unique_ptr<SceneNode> Ptr;
	typedef std::pair<SceneNode*, SceneNode*> Pair;


    public:
	explicit			SceneNode(Category::Type category = Category::None);

        void				attachChild(Ptr child);
        Ptr				detachChild(const SceneNode& node);

        void				update(sf::Time deltaTime, CommandQueue& commands);

	sf::Vector2f			getWorldPosition() const;
	sf::Transform			getWorldTransform() const;

	virtual unsigned int	        getCategory() const;
	void				onCommand(const Command& command, sf::Time deltaTime);

	void				checkSceneCollision(SceneNode& sceneGraph, std::set<Pair>& collisionPairs);
		void			checkNodeCollision(SceneNode& node, std::set<Pair>& collisionPairs);
	virtual sf::FloatRect	        getBoundingRect() const;

	void				removeWrecks();		
	virtual bool			isMarkedForRemoval() const;	
	virtual bool			isDestroyed() const;


    private:
        virtual void			draw(sf::RenderTarget& target, sf::RenderStates states) const final;
        virtual void		        drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
	void				drawChildren(sf::RenderTarget& target, sf::RenderStates states) const;
	void				drawBoundingRect(sf::RenderTarget& target, sf::RenderStates states) const;

        void				updateChildren(sf::Time deltaTime, CommandQueue& commands);
        virtual void			updateCurrent(sf::Time deltaTime, CommandQueue& commands);

    private:
        std::vector<Ptr>		children;
        SceneNode*			parent;
	Category::Type			defaultCategory;
    
};



Now to use a scene node you just stick a SceneNode in your game worlds class. For example.

1
2
3
4
5
6
7
8
class World
{
    ...
    ...

    private:
        SceneNode        sceneGraph;
};


sceneGraph will be the root node for your scene graph.


Now lets say you want to attach a SceneNode for the player's sprite that is on the screen? We would do something like this most likely.

1
2
3
4
5
6
7
8
// Aircraft is a derived class from SceneNode
std::unique_ptr<Aircraft> player(new Aircraft());

// Set whatever things you need to set before adding it as a child to another node.
player->setVelocity(40.0f,  0);

// Attach the player SceneNode to the Air SceneNode which holds as it's children all the aircraft entities.
airSceneNode->attachChild(std::move(player));


Now this probably wasn't the clearest explanation (In fact it was probably not even understandable ;p) but maybe it gave you a few ideas. I would suggest you read some tutorials on how SceneGraphs work since they will explain it much better then I tried to.

Also realize that this is only one way to manage your entities for a game. There are many different ways to do so and each has it's pros and cons.

Anyways wish you the best of luck with your game.
Last edited on
Topic archived. No new replies allowed.