Code: Select all
#include "includes.h"
#include <bitset>
#include <utility>
class Component;
class Entity;
class EntityManager;
using ComponentID = std::size_t;
using GroupID = std::size_t;
inline ComponentID getComponentTypeID()
{
static ComponentID cID = 0;
return cID++;
}
template <typename T>
inline ComponentID getComponentTypeID() noexcept
{
static ComponentID id = getComponentTypeID();
return id;
}
constexpr static ComponentID maxComponents = 32;
constexpr static GroupID maxGroups = 32;
using ComponentBitSet = std::bitset<maxComponents>;
using ComponentArray = std::array<Component*, maxComponents>;
using GroupBitSet = std::bitset<maxGroups>;
enum GroupLabels : std::size_t
{
groupMap,
groupPlayers,
groupEnemies,
groupCollider
};
class Component
{
public:
Entity* owner;
virtual void Update(const float& dt) {}
virtual void Init() {};
virtual void Draw() {};
};
class Entity
{
private:
ComponentBitSet m_componentBitset;
ComponentArray m_componentArray;
GroupBitSet m_groupBitSet;
std::vector<std::unique_ptr<Component>> m_components;
bool m_active = true;
EntityManager& manager;
public:
Entity(EntityManager& manager):manager(manager)
{};
virtual ~Entity() {}
virtual void Draw()
{
for (auto& comp : m_components)
comp->Draw();
};
virtual void Update(const float& dt)
{
for (auto& comp : m_components)
comp->Update(dt);
};
bool Active()const { return m_active; };
void Destroy() { m_active = false; }
template <typename Type>
bool HasComponent()const
{
return m_componentBitset[getComponentID<Type>()];
}
template <typename Type, typename... TArgs>
Type& AddComponent(TArgs&&... mArgs)
{
Type* comp(new Type(std::forward<TArgs>(mArgs)...));
std::unique_ptr<Component> uPtr{ comp };
m_components.emplace_back(std::move(uPtr));
m_componentArray[getComponentTypeID<Type>()] = comp;
m_componentBitset[getComponentTypeID<Type>()] = true;
comp->owner = this;
comp->Init();
return *comp;
}
template<typename Type>
Type& GetComponent()const
{
auto ptr(m_componentArray[getComponentTypeID<Type>()]);
return *static_cast<Type*>(ptr);
}
bool HasGroup(const GroupID& id)const
{
return m_groupBitSet[id];
}
void AddGroup(const GroupID& id);
void RemoveGroup(const GroupID& id)
{
m_groupBitSet[id] = false;
}
};
Code: Select all
void Game::InitPlayer()
{
// create entity
m_player = &m_entityMgr->Add();
// add components
// transform
TransformComponent* comp = &m_player->AddComponent<TransformComponent>(Vec2f({ 100.0f,100.0f }), Vec2f({ 0.0f,0.0f }), Vec2f({ 24.0f,32.0f }));
comp->acceleration = 56.0f;
comp->Scale(Vec2f(2.0f, 2.0f));
// sprite
TextureManager::ImageClip clip = m_textureHandler->GetClip("Colin", 1);
SpriteComponent* sprite = &m_player->AddComponent<SpriteComponent>(*clip.bitmap, clip.rect);
// animate the sprite
std::size_t myints[] = { 1,0,1,2 };
std::vector<std::size_t> indices(myints, myints + sizeof(myints) / sizeof(std::size_t));
sprite->AddAnimationSequence("walk_left", AnimationSeq(indices, 3, 300));
sprite->AddAnimationSequence("walk_down", AnimationSeq(indices, 2, 300));
sprite->AddAnimationSequence("walk_right", AnimationSeq(indices, 1, 300));
sprite->AddAnimationSequence("walk_up", AnimationSeq(indices, 0, 300));
// set to current sequnce
sprite->SetCurrentAnimationSeq("walk_left");
// add a keyboard component
m_player->AddComponent<KeyboardController>(*m_inputMgr.get());
// add attributes
m_player->AddComponent<DefenceComponent>();
m_player->AddComponent<AttackComponent>();
m_player->AddComponent<ExperienceComponent>();
m_player->AddComponent<VitalityComponent>();
m_player->AddComponent<MagicComponent>();
m_player->AddGroup(groupPlayers);
}
Code: Select all
#include "Components.h"
#include "Utils2D_v2.h"
class TransformComponent : public Component
{
D2D1_MATRIX_3X2_F matTrans = D2D1::Matrix3x2F::Identity();
D2D1_MATRIX_3X2_F matScale = D2D1::Matrix3x2F::Identity();
D2D1_MATRIX_3X2_F matRotation = D2D1::Matrix3x2F::Identity();
Vec2f center = { 0.0f,0.0f };
Vec2f size = { 0.0f,0.0f };
public:
TransformComponent() = default;
TransformComponent(Vec2f& p, Vec2f& v, Vec2f& s)
:position(p), velocity(v),size(s)
{}
virtual void Update(const float& dt)override
{
position += velocity * acceleration * dt;
Resize(size);
}
virtual void Init()override
{
center = Vec2f(position + (size * 0.5f));
};
Vec2f Center()const
{
return center;
}
Vec2f Dimensions()const
{
return size;
}
RectF Rect()
{
return{position.x,position.y,position.x + size.width,position.y + size.height};
}
void Resize(const Vec2f& dimensions)
{
size = dimensions;
center = Vec2f(position + (size * 0.5f));
}
D2D1_MATRIX_3X2_F Matrix()
{
return matRotation* matScale* matTrans;
}
void Rotate(const float& angle)
{
matRotation = D2D1::Matrix3x2F::Rotation(angle, center.ToD2DPointF());
}
void Scale(const Vec2f& dimensions)
{
matScale = D2D1::Matrix3x2F::Scale({dimensions.width, dimensions.height },
center.ToD2DPointF());
}
void Translate(const Vec2f& offset)
{
matTrans = D2D1::Matrix3x2F::Translation({ offset.x,offset.y }) * matTrans;
}
void Translate(const D2D1::Matrix3x2F& mat)
{
matTrans = mat * matTrans;
}
public:
Vec2f position = { 0.0f,0.0f };
Vec2f velocity = { 0.0f,0.0f };
float acceleration = 0.0f;
};