Last active
January 5, 2017 00:27
-
-
Save SeijiEmery/544f81ed22904ef8a1cc to your computer and use it in GitHub Desktop.
Entity Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef int64_t entity_id; | |
entity_id newUUID () { | |
entity_id id = 0; | |
return ++id; | |
} | |
enum class EntityType { | |
Empty, | |
Background, | |
Prop, | |
Enemy, | |
Player | |
}; | |
class Entity { | |
public: | |
// Constructors/destructors | |
Entity () : m_id(newUUID()) {} | |
virtual ~Entity () {} | |
// Shared methods | |
entity_id getId() const { return m_id; } | |
virtual EntityType getType () const { return EntityType::Empty; } | |
Vec2 getPosition() const { return m_pos; } | |
void setPosition (Vec2 pos) { m_pos = pos; } | |
void move (Vec2 offset) { m_pos += offset; } | |
virtual void doUpdate (float dt) {} | |
private: | |
entity_id m_id; | |
protected: | |
// protected setId (can only be called by subclasses or friends (iirc)) | |
void setId (entity_id id) { m_id = id; } | |
// Shared data | |
Vec2 m_pos; | |
}; | |
class Prop : public Entity { | |
public: | |
// Constructor | |
Prop (const Texture & texture) : | |
Entity(), m_texture(texture) {} | |
EntityType getType const override () { | |
return EntityType::Prop; | |
} | |
void draw (Renderer & renderer) { renderer.draw(m_texture, m_pos); } | |
protected: | |
Texture m_texture; | |
}; | |
class Background : public Entity { | |
// ... | |
}; | |
enum class EnemyType { | |
None, | |
Goblin, | |
Spider, | |
Skeleton | |
}; | |
class Enemy : public Entity { | |
public: | |
Enemy (const Sprite &sprite) | |
: Entity(), m_sprite(sprite) {} | |
EntityType getType const override () { | |
return EntityType::Enemy; | |
} | |
virtual EnemyType getEnemyType () const { return EnemyType::None; } | |
void draw (Renderer & renderer) { renderer.drawFrame(m_sprite, m_pos); } | |
void takeDamage (float damage) { | |
m_hp -= damage; | |
} | |
bool isDead () { | |
return m_hp < 0; | |
} | |
protected: | |
Sprite m_sprite; | |
float m_hp; | |
}; | |
class Goblin : public Enemy { | |
public: | |
Goblin () : Enemy(ResourceManager::getInstance().getGoblinEnemySprite()) {} | |
void doUpdate override (float dt) { | |
// do goblin update logic here... | |
// (walking, fighting, etc) | |
} | |
EnemyType getEnemyType () const override { | |
return EnemyType::Goblin; | |
} | |
}; | |
// ... | |
class GameManager { | |
public: | |
GameManager () {} | |
virtual ~GameManager () {} | |
template <typename T> | |
T & createEntity (const std::shared_ptr<T> & object) { | |
m_entities.emplace(object.getId(), std::static_ptr_cast<Entity>(object)); | |
return *object; | |
} | |
Goblin & createGoblin (float startingHp, Vec2 pos) { | |
auto & goblin = createEntity(std::make_shared<Goblin>()); | |
goblin.setHp(startingHp); | |
goblin.setPosition(pos); | |
return goblin; | |
} | |
std::vector<std::weak_ptr<Goblin>> getGoblins () const { | |
std::vector<std::weak_ptr<Goblin>> goblinList; | |
for (const auto & entity : m_entities) { | |
if (entity->getType() == EntityType::Enemy && | |
std::dynamic_ptr_cast<Enemy>(entity)->getEnemyType() == EnemyType::Goblin) | |
{ | |
goblinList.emplace_back( std::dynamic_ptr_cast<Goblin>(entity) ); | |
} | |
} | |
return goblinList; | |
} | |
void updateEntities (float dt) { | |
for (const auto & entity : m_entities) { | |
entity->doUpdate(dt); | |
} | |
} | |
// ... | |
protected: | |
std::map<entity_id, std::shared_ptr<Entity>> m_entities; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment