한 개체가 여러 분야를 서로 커플링없이 다룰 수 있게 한다.
#include <iostream>
using namespace std;
class GameObject {
public:
int velocity;
int x, y;
GameObject(InputComponent* input, PhsicsComponent* phsics, GraphicsComponent* graphics)
: input_(input), phsics_(phsics), graphics_(graphics) {}
void update(World& world, Graphic& graphics) {
input_->update(*this);
//속도에 따라 위치를 바꾼다.
phsics_->update(*this, world);
//알맞은 스프라이트를 그린다.
graphics_->update(*this, graphics);
}
private:
InputComponent* input_;
PhsicsComponent* phsics_;
GraphicsComponent* graphics_;
};
class InputComponent {
public:
virtual ~InputComponent() {}
virtual void update(GameObject& gameObj) = 0;
};
class BjornInputComponent : public InputComponent {
public:
virtual void update(GameObject& bjorn) {
switch (Controller::getJoystickDirection())
{
case DIR_LEFT:
bjorn.velocity -= WALK_ACCELERATION;
break;
case DIR_RIGHT:
bjorn.velocity += WALK_ACCELERATION;
break;
}
}
private:
static const int WALK_ACCELERATION = 1;
};
class DemoInputComponent : public InputComponent {
public:
virtual void update(GameObject& gameObj) {
// AI가 알아서 Bjorn을 조정한다...
}
};
class PhsicsComponent {
public:
virtual ~PhsicsComponent() {}
virtual void update(GameObject& gameObj, World& world) = 0;
};
class BjornPhsicsComponent : public PhsicsComponent{
public:
virtual void update(GameObject& bjorn, World& world) {
bjorn.x += bjorn.velocity;
world.resolveCollision(volume_, bjorn.x, bjorn.y, bjorn.velocity);
}
private:
Volume volume_;
};
class GraphicsComponent{
public:
virtual ~GraphicsComponent() {}
virtual void update(GameObject& gameObj, Graphics& graphics) = 0;
};
class BjornGraphicsComponent : public GraphicsComponent{
public:
virtual void update(GameObject& bjorn, Graphics& graphics) {
Sprite* sprite = &spriteStand_;
if (bjorn.velocity < 0) {
sprite = &spriteWalkLeft_;
}
else if (bjorn.velocity > 0) {
sprite = &spriteWalkRight_;
}
graphics.draw(*sprite, bjorn.x, bjorn.y);
}
private:
Sprite spriteStand_;
Sprite spriteWalkLeft_;
Sprite spriteWalkRight_;
};
int main() {
GameObject* gameObj = new GameObject(new BjornInputComponent(), new BjornPhsicsComponent(), new BjornGraphicsComponent());
}