I'm currently creating a game in SFML. To put it simply, I have an Object
class that has all the common features for all objects. Player
and Enemy
class inherit from Object
. There is also an ObjectManager
that has a list of all Object
and updates and draws them etc.
// using SFML shapes
class Player : public Object
{
public:
sf::CircleShape playerShape;
};
class Enemy : public Object
{
public:
sf::Sprite enemyShape;
};
class Object
{
public:
void move(...) { // move the shape, but the shapes are only found in the derived }
void draw(...) { // same problem as above, etc... }
};
class ObjectManager
{
private:
std::map<int, std::shared_ptr<Object>> gameObjectMap; // id, object
public:
void updateAll(...) {
// loop over all objects and update them
for (auto itr = gameObjectMap.begin(); itr != gameObjectMap.end(); ++itr) {
itr->second->move(...);
itr->second->draw(...);
}
}
};
Above you can see that Object::move()
cannot be used because Object
does not know about the SFML shapes in the derived classes. Therefore you could make the function Object::move()
pure virtual but this means that you'd need to write implementations in the derived classes for any shape specific function that you need to use, this also includes any attributes about the shape, such as its position sf::Shape::getPosition()
, etc. So this approach does not scale well.
An alternative that I thought about would be to have the Object
class as a class template
template<typename T>
class Object
{
protected:
T object;
public:
void move(...) { object.move(...); }
T getObject() { return object; }
};
class Player : public Object<sf::CircleShape>
{ ... };
However this means that ObjectManager
now must hold class templates Object
in the map, and I'm not sure how that would work?
What's the best way to handle this situation?