디자인 패턴/게임 프로그래밍 패턴

[게임 프로그래밍 패턴][7]상태 패턴

우향우@ 2024. 4. 24. 10:17

개요

상태 패턴은 FSM과 같이 상태에 따라 다른 동작을 수행하는 클래스를 만드는 기법이다. 그러한 동작을 수행할 클래스를 A라고 하자. 상태를 정의하는 상위 상태 클래스에서 Input처리 메소드, Update 메소드 등을 A의 레퍼런스를 받아 처리하는 가상 메서드로 정의한다. 그리고 각 상태 클래스에서 이를 상속받아 A가 해당 상태일때 해당 메소드에서 처리할 수행을 구현한다. A에서는 현재 상태를 나타내는 상태 객체의 포인터를 가지고 input처리, update등에서 해당 객체의 해당 메소드에 자신을 넘겨 처리한다. 만약 그로인해 상태가 변한다면 상태 클래스의 해당 메서드에서 변한 상태 객체 포인터를 리턴하고 A는 그것을 받아 새로 장착한다.

또한 각 상태 객체는 자신의 필드를 가져 상태에서 사용할 변수를 운용할 수도 있다.

추가로 상태에 입장, 퇴장할 때 호출할 가상 메소드도 구현하고 A에서 상태가 변할때 이들을 호출해주면 상태 변화에 따른 처리도 구현할 수 있다.

 

확장

하나의 상태를 가져 구현하는 FSM은 표현력에 한계가 있다. 이를 극복하기 위한 확장 기법들을 살펴보자.

 

병행 상태 기계

A에서 2개 이상의 FSM을 가지는 기법이다. 상,하체에 대한 FSM을 별도로 가지는 등이 될 수있다. 만약 두 상태 기계가 독립적으로 작동한다면 좋은 기법이 되겠지만 서로 상호작용 해야한다면 코드가 복잡해져 적합하지 않을 수 있다.

 

계층형 상태 기계

일부 동작이 같은 상태 클래스가 여러개 존재할 수 있다. 이를 상속으로 해결해보자. 예를 들어 서기, 걷기, 달리기 등의 상태에서 점프키를 누르면 점프 상태로 변환하는 동작을 수행할 것이다. 이를 세개의 상태 모두에서 구현하기보다는 상속으로 묶는게 좋다. GroundState라는 상위 클래스를 만들고 점프키가 눌릴때 점프를 하는 동작을 구현한다. 위 세개의 상태에서는 이를 오버라이드하여 자신의 입력에 대한 처리를 먼저 수행하고 거기서 처리되지 못한 입력은 GroundState의 입력처리에 넘겨 처리하도록 한다. 이렇게 하면 코드 중복을 막을 수 있다.

 

푸쉬 다운 오토마타

FSM은 현재의 상태만 유지할뿐 이전 상태들의 히스토리는 기억하지 못한다. 푸쉬 다운 오토마타는 상태 전이를 할때 원한다면 이전 상태의 히스토리를 유지할 수 있다. 만약 사격이라는 상태가 있다고 하자. 플레이어는 서기, 앉기, 엎드리기 등 여러 상태에서 사격을 할 수 있다. 이때 사격이 끝나면 사격하기전 상태로 돌아가야하는데 FSM에서는 사격 이전의 상태를 모르기에 쉽게 구현할 수 없다. 푸쉬다운 오토마타에서는 저장해둔 이전 상태로 돌아기기만 하면 된다.

이는 스택으로 구현할 수 있다. 스택의 맨위 상태가 현재 상태를 나타낸다. 상태 전이는 다음 두 동작들을 이용하여 전이한다.

1. 새 상태를 스택에 넣기

2. 최상위 상태를 스택에서 빼기

최상위 상태를 빼고 새 상태를 집어넣는다면 그냥 이전 상태에서 덮어씌우며 전이하는것이라 볼 수 있다. 최상위 상태를 빼지 않고 새 상태를 바로 스택에 넣으면 이전 상태를 저장하며 새 상태로 전이한 것이다. 그렇게 전이한 후 최상위 상태를 그냥 스택에서 뺀다면 이전 상태로 다시 돌아가는 것으로 전이했다고 볼 수 있다. 이를 통해 사격 후 다시 원래 상태로 돌아 갈 수 있다.

 

 

 

 

참고서적

게임 프로그래밍 패턴