I'm a fairly experienced programmer, but I'm still relatively new to OOP architecture and design in c++.
Most of my experience is with C# and Java. I recently endeavored to code up a simple game engine in c++.
I used SDL for the graphics. In this post, I would like to discuss my architecture and to get some feedback
on it. Particularly, I've run into a design issue that I would like some help with. So, here goes:
In my main function, I initialize all of the SDL stuff for drawing to the screen, etc.
Then I instantiate all of the objects that I intend to use: floor, wall, player, etc.
Next I start the main loop. This loop executes each object's movement, collision detection and collision handling functions, and redraws them.
The main loop runs until the application is quit, drawing one frame each iteration.
My problem is this:
I tried to do a kind of interface-style design. It involves a series of
abstract base classes that allow each object to implement a behavior. For example, if I want an object to be movable,
it would have to inherit from the movable base class which contains a virtual function called move() and some position
coordinates. If I wanted it to be collidable, the object would inherit from the collidable abstract class, which
contains the virtual functions checkCollision() and handleCollision() as well as a hitbox member variable. An object
like the player inherits from both of these base classes as well as several others.
This works well enough as long as I'm doing everything by hand in the main loop. I can just say:
player.move();
player.checkCollision();
player.handleCollision();
player.draw().
and it's fine. But I would like to
be able to have a vector or array of generic objects in the main loop and do something like this:
for each object in vector
if object is of type movable
object.move();
if object is of type collidable
object.checkCollision();
I thought that I could accomplish this with dynamic casting, but I really haven't been able to come up with anything.
I've tried storing them as void pointers, but that doesn't work the way I want it to. I've been reading about this
gameobject-component architecture for video games that I might try, but I'd really like to salvage what I've already
written. I figure this is a good learning opportunity. If anybody has any ideas I'd really appreciate it. How does my architecture compare to other simple game engine designs? does my interface architecture make sense or is it totally wonky?
If you work in C++, try SFML, it's faster than SDL, and if you know OpenGL, you can use it too.
For your problem:
class Entity {
//constructor and other stuff
void virtual exec() =0; ///<= pure virtual method
};
class Movable : Entity {
void move(); //do somthing
void exec() {move();};
};
class Collidable : Entity {
void col(); //do your job
void exec(){col();};
};
std::vector<Entity*> e_v;
///push some instance
for (Entity* e : e_v)
e->exec();
What about using the template method pattern and non-abstract empty virtual functions in the base class?
class Entity
{
void update()
{
move();
checkCollision();
}
virtual void move() {}
virtual void checkCollision() {}
};
class Movable : public virtual Entity
{
virtual void move() {} // Stuff
};
class Collidable : public virtual Entity
{
virtual void checkCollision() {} // Stuff
};
Related
I'm working on a game for an assignment and I've ran into an issue with function overriding in C++.
I have the following structure:
class GameEntity
{
public:
bool GameEntity::TakeHit(int dmg);
};
class Enemy : public GameEntity
{
bool Enemy::TakeHit(int dmg);
};
When from another class I create an instance of an Enemy, store it in a GameEntity vector, then call TakeHit() on it, it's calling the GameEntity version of it. I'm used to Java where this would call the other version, am I doing something obviously wrong here?
Other questions don't really cover this so I've created my own.
It's probably something pretty simple I'm guessing, so apologies for the trouble.
Make TakeHit a virtual member function.
// You don't need the scope specifier GameEntity::
// Make it pure virtual to force sub-classes to implement them.
virtual bool TakeHit(int dmg) = 0;
Store pointers to objects, preferably smart pointers, instead of objects. If you store just objects, you suffer from object slicing problem.
The function from GameEntity needs the virtual keyword.
I have a class Game with class EnemyManager. EnemyManager deals with spawning of enemies and the logic behind it. The problem is that EnemyManager needs access to functions and other Game objects in the game class. I can think of two ways to handle this.
Pass the address of the class object Game* using this as one of the arguments in the EnemyManager.
Declare a global pointer to a Game object and set it when initializing the Game class. Then extern it into the enemymanager.cpp.
Which is the more advisable way to do this?
Whenever I encounter situations like this I review the overall design of the related classes. If EnemyManager is a member of a Game object and needs to call things within Game, maybe those functions in Game can be factored out into a separate component. If something you are writing is beginning to feel overly-complex or like a hack it's usually time to do some factoring.
When dealing with object oriented designs, it is typically good to think about who will act how on what to find a first version of a design. After having written this version, one often finds the weaknesses and rewrite it for the second iteration.
So, in this case, the Game class manages the world (I assume) and offers different ways to manipulate it. Your EnemyManager manages one aspect of the world, enemies, but they do live inside the world.
class Enemy {
public:
Enemy(Location& location, int hitpoints);
bool Move(Direction& direction);
};
class Game {
public:
bool CreateInitialState();
bool AddEnemy(Enemy& enemy);
bool AddBullet(Location& location, Direction& direction, int speed);
void Render();
};
class EnemyManager {
public:
EnemyManager(Game& game);
void MoveEnemies();
};
In this first version, all types see each other as proper classes and manipulates things by calling the appropriate method. This offers little support for expanding on the game if you want to add new things to it.
This is where interfaces become handy and you can try to think about how the different parts will interact instead of how they should be implemented.
class Canvas {
public:
// Different graphical primitives.
};
class GameObject {
public:
virtual ~GameObject() {};
virtual void Draw(Canvas& canvas) = 0;
virtual bool Move(Direction& direction) = 0;
};
class GlobalState {
public:
virtual AddGameObject(GameObject& gameObject) = 0;
};
class Game : public Canvas, public GlobalState {
public:
bool CreateInitialState();
void Render() {
// Send itself to the Draw method in all GameObjects that have been added
}
// Other game logic
};
class Enemy : public GameObject {
// This can be specialized even more if you need to
};
class Bullet : public GameObject {
// This can also be specialized even more if you need to
};
This separates design from implementation and, as I see it, is a good way to end up with a proper first attempt.
It is hard to say without knowing the overall architecture layout, but my 2 cents:
The way you describe as a first one is called the dependency injection and is widely used all around. You should keep an eye on what methods/fields you're making public.
I assume that Game class has the methods that should not be accessible from the EnemyManager class, thus is seems like it's a good idea to create the interface which has the declaration of the methods that are used by EnemyManager and then pass the pointer to the EnemyManager instance (instead of the Game).
For example: The Game class implements IGameEnemyManager, and you're passing IGameEnemyManager using this as one of the initialization arguments.
If you are handling game objects in EnemyManager, why is it part of the class Game ? I suppose you should consider reviewing your design as there are chances of circular reference problem if you don't handle the scenarios well.
Consider segregating both the classes to ensure a single responsibility principle.
Define proper interface in yourEnemyManagerto Game object as argument and act on the functions
These are little suggestions that I can think of with limited idea about your design
You're absolutely need to use the 1st approach, but with a few changes: you should disintegrate your Game class to more components. For example you can create a SceneManager class, which is responsible for all game object's creation/management. When you're instantiating the EnemyManager - just pass a pointer to it:
// in SceneManager
EnemyManager* emgr = new EnemyManager(this);
InterfaceManager* imgr = new InterfaceManager(this);
Note that your SceneManager class should provide a complete interface
// in EnemyManager
GameObject* spawnEnemyAt(string name, EnemyClass* eclass, Vector3 position, AIBehaviour* behaviour)
{
GameObject* myEnemy = smgr->createGameObject(name, position, etc...);
//register an enemy in the enemies list, initialize it's behaviour and do any other logic
return myEnemy
}
This approach should help you not to ruin your architecture and not to be captured in the friend(class)-zone.
[Upd.] Note that my approach assumes that all objects on the scene are GameObjects, there's neither Enemy nor Player classes. Every GameObject may has a Renderer, Animator, AIBehaviour components.
I'm writing a simple 2D game centered around mazes with RPG elements. It is primarily for learning purposes to practice class design, graph theory algorithms, data structure use, and using 2D graphics.
Brief Overview of the Program:
The game itself is tile based. It currently generates and draws mazes to the screen, allows for player movement, and collision detection for walls; in addition it can handle screen scrolling for larger mazes.
Anyway, right now I'm working on building an object which handles placing objects around the map. First on the list is gold coins, then things like hearts and items. I thought this would be a good time to practice inheritance and polymorphism, but I haven't had any formal training in this kind of design. Here is the header file:
#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H
#include "Common.h"
#include "Utility Functions.h"
const int TILE_SIZE = 80;
class MapObject
{
public:
MapObject(unsigned int nClips, unsigned int r, unsigned int c, unsigned int cSize) :
sheet(0), clips(0), row(r), col(c), numClips(nClips), clipSize(cSize)
{
//For those of you who aren't familiar with sprite sheet usage, basically this
// handles which part of the sprite sheet your on, so it will draw the correct sprite to the screen
if(numClips > 0) clips = new SDL_Rect[numClips];
box.h = clipSize;
box.w = clipSize;
}
virtual ~MapObject() //NOt sure if this is right. All the derived classes will
// behave the same upon deletion, since the only resource
// that got allocated was for the box SDL_rect
{
if(clips) delete[] clips;
}
void initBox(int modX, int modY);
//I think each object will draw a little different, so I made it virtual
virtual void draw() = 0;
//Same with interaction--although I'm not sure how my player class is going to be able to handle this yet
virtual void interact() = 0;
SDL_Rect getBox() const;
private:
SDL_Surface* sheet;
SDL_Rect box;
SDL_Rect* clips;
unsigned int row, col;
unsigned int numClips;
unsigned int clipSize;
MapObject() {} //Made this private because I want the memory to be allocated, and
// numClips needs to be initialized for that to happen, so
//basically I'm forcing the user to use the constructor with parameters
};
class Coin : public MapObject
{
enum CoinFace //This represents all the different coin facings in the sprite
//sheet, so that is can animate. Used in the draw function.
{
FRONT,
TURN1,
TURN2,
TURN3,
USED
};
CoinFace active;
public:
virtual void draw(SDL_Surface* destination);
virtual void interact();
};
#endif //MAP_OBJECTS
My biggest question is a general one: is this a good start to my design? Are their glaring problems? Misuses of OOD principles/conventions?
Will defining the virtual destructor like that allow for all the derived classes to use it? Or do I need to define it for each derived class?
I realize this is a lot, and I appreciate any help. I'm REALLY trying to understand OOD and how to use polymorphism, so help from some pros would be incredibly useful.
Thanks again.
EDIT: Big question I have also is the problem of begin able to modify private data members in the derived classes. I hear it's bad class design if I need to do this, and I'm not sure how to write a good interface, I guess.
Part of the question relies on a matter of opinions. Nevertheless:
All I can say here is that your approach can work, and you're well on your way to have that working. Just don't forget to define the constructor of Coin.
The whole purpose of the virtual destructor is to call the appropriate destructor when we only have a pointer of a base class type. In addition, the derived destructor is performed before the base destructor is automatically called, without having to call it explicitly. In this case, a Coin pointed by a MapObject* will be destroyed correctly with delete, which performs ~Coin() and ~MapObject(), in this order.
That question can easily turn into a debate on proper interface construction, but here are a few solutions:
Define private members via the constructor, preventing them from being modified by other classes.
Make members in a base class protected instead of private. This might be the simpler solution to what you wish to do here.
Create setters for the private member types, like setActive(CoinFace). You can adapt these functions to your needs, like preventing invalid definitions for an attribute that would make the whole object inconsistent. Like the previous solution, you can make these setters protected, so that only derived classes can access them.
Make the class a friend of another class (calling it A). Instances of A can take objects of that class and access all its private members.
I read so many blogs and I understand how to use virtual function in c++. But, still I don't understand why we use virtual functions. Can you give me a real world example so that I can more easily visualize the actual meaning of virtual function.
An important thing to mention is that inheritance (which the keyword virtual is fundamental for) should not be for the sole purpose of code re-use, use delegation for this.
Delegation would be when we have a class say BroadbandConnection with a method called connection(). Then your manager says we want to add encryption, so you create a class BroadbandConnectionWithEncryption. Your natural instinct may be to use inheritance and then make the new class BroadbandConnectionWithEncryption derive from BroadbandConnection.
Drawback's to this is that the creator of the initial class had not designed it for inheritance so you would need to change its definition to make the method connection() virtual so you can override its behavior in the derived class. This is not always ideal. A better idea is to use delegation here for the purpose of code reuse.
class BroadBandConnection
{
public:
void Connection (string password)
{
//connection code.
}
};
class BroadBandConnectionWithEndcryption
{
public:
void Connection (string password)
{
mbroadbandconnection.Connection(password);
//now do some stuff to zero the memory or
//do some encryption stuff
}
private:
BroadBandConnection mbroadbandconnection;
};
The keyword virtual is used for the purpose of polymorphism. As the name suggest, it is the ability for an object to have more than one form. This sort of decision would be made at the time of designing an interface or class.
class IShape
{
virtual void Draw () = 0;
};
class Square
{
void Draw()
{
//draw square on screen
}
};
class Circle
{
void Draw()
{
//draw circle on screen
}
};
I made Draw() pure virtual with the = 0. I could have left this out and added some default implementation. Pure virtual makes sense for Interfaces where there is no reasonable default implementation.
What this lets me do is pass around a Shape object to various methods and they do not need to be concerned with what I have just given them. All they know is that I have to provide something that supports the ability for a shape to draw itself.
IShape* circle = new Circle ();
IShape* square = new Square ();
void SomeMethod (IShape* someShape)
{
someShape->Draw(); //This will call the correct functionality of draw
}
In the future as people begin thinking of new shapes, they can derive from IShape and so long as they implement some functionality for Draw. They can pass this object to SomeMethod.
First, this.
Now, a real life example. I have a program with a GUI with three tabs. Each tab is an object of a class that derives from a common base, TabBase. It has a virtual function OnActivate(). When a tab is activated, the dispatcher calls it on the current tab. There's some common action and there are actions that are specific to this tab. This is implemented via virtual functions.
The benefit is that the controller does not need to know what kind of tab it is. It stores an array of TabBase pointers, and just calls OnActivate() on them. The magic of virtual functions makes sure the right override is called.
class TabBase
{
virtual void OnActivate()
{
//Do something...
}
};
class SearchTab: public TabBase
{
void OnActivate() //An override
{
TabBase::OnActivate(); //Still need the basic setup
//And then set up the things that are specific to the search tab
}
}
We have one base class (animal) that have method, that can be implemented differently by it's children (say). When we declare this method virtual, we can adress that method and it will be implemented from it's children's definition. You don't have to use virtual if you adress children's overloaded methods, but you have to, when you adress parent's methods.
For example, if you have a vector of animals each one of whom is different. You declare method (say) as virtual and call it from animal class and it will be called from corresponding child.
Correct me if I'm wrong, that's how I understood it.
They actually give an example on Wiki
http://en.wikipedia.org/wiki/Virtual_function
using animals. Animals is the super class, all animals eat (the superclass virtual function). Each animal may eat differently than all the other animals (overriding the virtual function). I have a list of arbitrary animals, and when I call the eat function, they will display their own differing eating habit.
If you are familiar with Java - that should be easy. In Java, ALL class methods are effectively virtual. If you override it in a derived class, and you call it via a base class reference, the override will be called, not the base.
That's not the default behavior in C++. If you want a function to behave in that way, you have to declare it as virtual in the base class. Easy enough.
Java is choke full of virtual functions. It just does not have an explicit keyword for them.
The purpose of virtual functions is to achieve dynamic dispatch.
You say you are familiar with Java, so then for a real world use of virtual functions, think of any place in Java where you would have used an interface or used #Override on a public/protected method.
The decision to use virtual functions is a simple matter. You just need to know when you'd want to override a base method. Take the following code as an example:
class animal
{
public:
void sound()
{
cout << "nothing";
}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
In this case, I'd want to override bird(). But what if I didn't? This is what would happen:
animal * a = new bird;
a->sound();
**Output**
nothing
The screen would say nothing because for all intents and purposes, C++ only sees an animal. However, if you declared it virtual, it knows to search for the lowest method in the class hierachy. Try it again:
class animal{
public:
virtual void sound(){cout<<"nothing";}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
animal * a = new bird;
a->sound();
**Output**
tweet.
Hope this helps.
Suppose I have following inheritance tree:
SDLBullet inherits from Bullet inherits from Entity
EnemyBullet inherits form Bullet inherits from Entity
Now I need a new class, SDLEnemyBullet, which needs the draw as implemented in SDLBullet, and the collision as implemented in EnemyBullet. How would I do this? Is this to be solved using multiple inheritance? If not, feel free to edit my question and title. If so, how would I implement such thing?
Some code examples below:
class Entity {
bool collision(Entity) = 0;
void draw() = 0;
}
class Bullet : Entity {
bool collision(Entity) {/*some implementation*/};
void draw() {/*draw me*/};
}
class SDLBullet : Bullet {
void draw() {/*draw me using SDL*/};
}
class EnemyBullet : Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
}
class SDLEnemyBullet : ????? {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
Any help is much appreciated!
(BTW: This is a school project, and an inheritance tree like this was suggested to us. No one is stopping us from doing it different and better. Thats why I asked the question.)
The textbook solution involves multiple and virtual inheritance.
class SDLBullet : public virtual Bullet {
void draw() {/*draw me using SDL*/};
};
class EnemyBullet : public virtual Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
};
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
// just one Bullet subobject here
};
Normally, collision stuff is done using multiple dispatch, or in C++, who hasn't this feature, using the visitor pattern.
BUT
why don't you have a hierarchy like this instead ?
class Entity;
class Bullet : public Entity
{
public:
virtual draw();
}
class FriendlyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
class EnnemyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
This would work too, and wouldn't require multidispatch or multiple inheritance
You need to specify a comma separated list of the super classes:
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
It looks like you're making a game (engine). To avoid the need for complex inheritance structures like this favor composition over inheritance for entities i.e. Have an entity object that contains separate 'component' objects for rendering etc. That way you can mix and match the components however you like without having an explosion of classes with all the different combinations of super classes.
Here's a good article on the subject: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
Prefer composition over inheritance
You don't need inheritance to combine stuff that's not related like that. Make up basic objects (entities?) for game logic, physics, sound, input, graphics (which may use inheritance) and combine those a GameObject which just has an array of said objects.
Some nifty cross-linking is useful since they will all share a Frame or Transform, but that can be done during creation by iterating over all other objects and using dynamic_cast... (it's useful if you do not need to depend on initialization order).
But there's really no need to build this with inheritance. It doesn't fit your usecase properly. (Although virtual inheritance is useful, it's not a good thing to use inheritance to force different things to become the same, i.e. making everything be a something, instead of being made up of different parts (render, damage, sound, etc...).
Read this and this for more info, or just click the title to google for it. :)