728x90
1. 컴포넌트 패턴 정의
- 한 개체가 여러 분야를 서로 커플링 없이 다룰 수 있게 한다.
2. 커플링 된 함수
if ( CollidingWithFloor() && ( GetRenderState() != ERanderState::INVISIBLE ) )
{
PlaySound( ESound::HIT_FLOOR );
}
- 물리 ( CollidingWithFloor() ), 그래픽 ( GetRenderState() ), 사운드 ( PlaySound() )가 커플링 된 소스 코드
- 소스 코드 수정을 위해서는 위 3가지 항목을 전부 알아야 하기에 유지보수가 힘들다.
3. 커플링 된 클래스
class GameObject
{
private:
static const int WALK_ACCELERATION = 1;
int Velocity;
int X, Y;
FVolume Volume;
FSprite SpriteStand;
FSprite SpriteWalkLeft;
FSprite SpriteWalkRight;
public:
GameObject() : Velocity( 0 ), X ( 0 ), Y ( 0 ){}
void Update( FWorld& InWorld, FGraphics& InGraphics )
{
// 입력에 따라 주인공의 속도를 조절한다.
switch ( Controller::GetJoystickDirection() )
{
case Direction::Left:
Velocity -= WALK_ACCELERATION;
break;
case Direction::Right:
Velocity += WALK_ACCELERATION;
break;
}
// 속도에 따라 위치를 바꾼다.
X += Velocity;
InWorld.ResolveCollision( Volume, X, Y, Velocity );
// 알맞은 스프라이트를 그린다
FSprite* sprite &SpriteStand;
if ( Velocity < 0 )
sprite = &SpriteWalkLeft;
else if ( Velocity > 0 )
sprite = &SpriteWalkRight;
InGraphics.Draw( *sprite, X, Y );
}
};
- Update 함수 안에 물리엔진 / 그래픽 엔진 등 함수들이 커플링 되어 있다.
3. 분야별로 컴포넌트화
class InputComponent
{
private:
static const int WALK_ACCELERATION = 1;
public:
void Update( GameObject& InGameObject )
{
// 입력에 따라 주인공의 속도를 조절한다.
switch ( Controller::GetJoystickDirection() )
{
case Direction::LEFT:
InGameObject.Velocity -= WALK_ACCELERATION;
break;
case Direction::RIGHT:
InGameObject.Velocity += WALK_ACCELERATION;
break;
}
}
};
class PhysicsComponent
{
private:
FVolume Volume;
public:
void Update( GameObject& InGameObject, FWorld& InWorld )
{
InGameObject.X += InGameObject.Velocity;
InWorld.ResolveCollision( Volume, InGameObject.X, InGameObject.Y, InGameObject.Velocity );
}
};
class GraphicsComponent
{
private:
FSprite SpriteStand;
FSprite SpriteWalkLeft;
FSprite SpriteWalkRight;
public:
void Update( GameObject& InGameObject, FGraphics& InGraphics )
{
// 알맞은 스프라이트를 그린다
FSprite* sprite = &SpriteStand;
if ( InGameObject.Velocity < 0 )
sprite = &SpriteWalkLeft;
else if ( InGameObject.Velocity > 0 )
sprite = &SpriteWalkRight;
InGraphics.Draw( *sprite, InGameObject.X, InGameObject.Y );
}
};
class GameObject
{
private:
InputComponent Input;
PhysicsComponent Physics;
GraphicsComponent Graphics;
public:
int Velocity;
int X, Y;
public:
GameObject() : Velocity( 0 ), X ( 0 ), Y ( 0 ){}
void Update( FWorld& InWorld, FGraphics& InGraphics )
{
Input.Update( *this );
Physics.Update( *this, InWorld );
Graphics.Update( *this, InGraphics );
}
};
- 각 분야별로 입력, 물리, 그래픽을 컴포넌트화 하여 분리한다.
4. 컴포넌트 추상화
class InputComponent
{
public:
virtual ~InputComponent() {}
virtual void Update( GameObject& InGameObject ) = 0;
};
class PlayerInputComponent : public InputComponent
{
private:
static const int WALK_ACCELERATION = 1;
public:
virtual void Update( GameObject& InGameObject ) override
{
// 입력에 따라 주인공의 속도를 조절한다.
switch ( Controller::GetJoystickDirection() )
{
case Direction::LEFT:
InGameObject.Velocity -= WALK_ACCELERATION;
break;
case Direction::RIGHT:
InGameObject.Velocity += WALK_ACCELERATION;
break;
}
}
};
- 추상 상위 클래스를 만들어, 사용자에 맞춰 컴포넌트를 정의하여 사용할 수 도 있다.
반응형
'Design Pattern > 게임 프로그래밍 패턴' 카테고리의 다른 글
[Design Pattern] 서비스 중개자 패턴 (0) | 2022.08.12 |
---|---|
[Design Pattern] 이벤트 큐 패턴 (0) | 2022.08.05 |
[Design Pattern] 하위 클래스 샌드박스 패턴 (0) | 2022.08.02 |
[Design Pattern] 바이트 코드 패턴 (0) | 2022.08.02 |
[Design Pattern] 업데이트 메서드 패턴 (0) | 2022.08.01 |