Using James Mansfield's 2D engine. This retro game clone was a very interesting project to work on because I did two iterations on it. The first one using an object oriented approach with high emphasis on how classes were related to each other. The second one was using a component-based system to build independent and interchangeable modules.
/*
* Carlos Adan Cortes De la Fuente
* All rights reserved. Copyright (c)
* Email: dev@carlosadan.com
*/
class GameObject
{
private:
std::vector<Component*> mComponents;
public:
GameObject() {}
~GameObject()
{
for (Component* pComponent : mComponents)
{
pComponent->Destroy();
delete pComponent;
}
}
void Initialize()
{
for (Component* pComponent : mComponents)
{
pComponent->Initialize();
}
}
void AddComponent(Component* pComponent)
{
mComponents.push_back(pComponent);
}
template<class T>
T* FindComponent(ComponentType eType)
{
for (Component* pComponent : mComponents)
{
if (pComponent->GetType() == eType)
{
return (T*)pComponent;
}
}
return nullptr;
}
};
/*
* Carlos Adan Cortes De la Fuente
* All rights reserved. Copyright (c)
* Email: dev@carlosadan.com
*/
class Component
{
public:
Component(GameObject* pGO): mGO(pGO) {}
~Component() {}
virtual ComponentType GetType() const = 0;
virtual void Initialize() {}
virtual void Destroy() {}
GameObject* GetGameObject() const { return mGO; }
protected:
GameObject* mGO;
template<class T>
void AddToComponentVector(std::vector& componentVector)
{
componentVector.push_back((T*)this);
}
template<class T>
void RemoveFromComponentVector(std::vector& componentVector)
{
componentVector.erase(std::remove(componentVector.begin(), componentVector.end(), this), componentVector.end());
}
};
/*
* Carlos Adan Cortes De la Fuente
* All rights reserved. Copyright (c)
* Email: dev@carlosadan.com
*/
class COGBounce : public Component, public IPhysicsCollisionEvent
{
public:
static std::vector<COGBounce*> mBounceComponents;
COGBounce(GameObject* pGO) : Component(pGO) {}
~COGBounce() {}
virtual ComponentType GetType() const { return ComponentType::Bounce; }
virtual void Initialize() override
{
AddToComponentVector(mBounceComponents);
// Registers itself to the collision events
mGO->FindComponent<COGPhysics>(ComponentType::Physics)->AddListener(this);
}
virtual void Destroy() override
{
RemoveFromComponentVector(mBounceComponents);
}
virtual void OnCollision(COGPhysics* pMe, COGPhysics* pOther, exCollision collision) override
{
// Changes the velocity of the ball so it bounces off the surfaces
exVector2& velocity = pMe->GetVelocity();
float transformation = 2 * (velocity.x * collision.normalX + velocity.y * collision.normalY);
collision.normalX *= transformation;
collision.normalY *= transformation;
velocity.x -= collision.normalX;
velocity.y -= collision.normalY;
}
};
// Init static vector
std::vector<COGBounce*> COGBounce::mBounceComponents;