객체의 내부 상태에 따라서 스스로 행동을 변경 할 수 있는 패턴으로, 이렇게 하면 객체가 내부에서 마치 자신의 클래스를 바꾸는 것처럼 사용할수 있다.
상태패턴에서는 finite state machine (FSM) 을 언급할 수밖에 없다. 그러다 보니 hierarchical state machine(HSM) 과 pushdown automata까지 이어졌다.
많은걸 다루다보니 분량 조절을 위해서 세세한 부분은 설명하지 않겠다. 우리한테 중요한건 큰 그림을 그리고 파악하는 것이다.
간단한 횡스크롤 플랫포머를 만든다고 보자. 게임월드의 주인공이 사용자 입력에 따라서 이동하도록 구현해야한다. B버튼을 누른다면 점프를 한다고 생각해보자.
void Heroine::handleInput(Input input)
{
if (input == PRESS_B)
{
yVelocity_ = JUMP_VELOCITY;
setGraphics(IMAGE_JUMP);
}
}
자세히 들여다보면 버그가 보일 것이다. 어디서든 점프가 가능하다. 즉 공중에서도 점프가 가능할 것이다. 그러면 해당 공중점프를 막아야 한다. bool 변수를 추가해서 막아보자.
void Heroine::handleInput(Input input)
{
if (input == PRESS_B)
{
if (!isJumping_)
{
isJumping_ = true;
// Jump...
}
}
}
주인공이 땅에 있을 때 아래버튼 누르면 엎드리고, 버튼을 때면 다시 일어나는 기능을 추가해보자.
void Heroine::handleInput(Input input)
{
if (input == PRESS_B)
{
// Jump if not jumping...
}
else if (input == PRESS_DOWN)
{
if (!isJumping_)
{
setGraphics(IMAGE_DUCK);
}
}
else if (input == RELEASE_DOWN)
{
setGraphics(IMAGE_STAND);
}
}
이번에도 버그를 찾아보자. 어떤것이 보이는가?
이런걸 방지하기 위해서 플래그 변수가 더 필요할 것이다.
void Heroine::handleInput(Input input)
{
if (input == PRESS_B)
{
if (!isJumping_ && !isDucking_)
{
// Jump...
}
}
else if (input == PRESS_DOWN)
{
if (!isJumping_)
{
isDucking_ = true;
setGraphics(IMAGE_DUCK);
}
}
else if (input == RELEASE_DOWN)
{
if (isDucking_)
{
isDucking_ = false;
setGraphics(IMAGE_STAND);
}
}
}
점프중에 아래 버튼 눌러 내려찍기 공격을 할 수 있게 해보자.
void Heroine::handleInput(Input input)
{
if (input == PRESS_B)
{
if (!isJumping_ && !isDucking_)
{
// Jump...
}
}
else if (input == PRESS_DOWN)
{
if (!isJumping_)
{
isDucking_ = true;
setGraphics(IMAGE_DUCK);
}
else
{
isJumping_ = false;
setGraphics(IMAGE_DIVE);
}
}
else if (input == RELEASE_DOWN)
{
if (isDucking_)
{
// Stand...
}
}
}