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

[게임 프로그래밍 패턴][2]Command 패턴

우향우@ 2024. 4. 19. 10:02

개요

Command 패턴은 어떤 수행이나 동작을 실체화시켜 사용하는 것을 말한다. 여기서 실체화는 클래스등의 인스턴스로 만들어 사용한다는 이야기이다.

이는 함수 포인터, 함수 객체와 비슷한 효과를 낸다. 하지만 거기에 더하여 클래스의 멤버로 수행의 상태를 저장하거나 undo등의 관련 수행들을 묶어 만드는등 더 디테일한 구현을 하는 패턴이다.

 

사용 예시

 가장 간단한 예시는 가상 메서드 하나를 가진 Command 추상 클래스이다. 가상 메서드의 이름을 void excute()라 하자. 이 클래스를 상속하여 excute를 오버라이드하면 Command*를 저장하거나 받아 사용하는 부분에 자식 클래스들을 넣어 해당 클래스의 excute를 실행하도록 할 수 있다.

여기서 특정 엑터가 수행하는 동작을 만든다고 하자. 위 방식에서 JumpCommand를 만든다고하면 excute안에서 점프할 대상을 찾고 그 대상이 점프하도록 해야할 것이다. 이는 그 대상과 JumpCommand사이에 커플링이 발생하여 구조적으로 좋지 못하다. excute를 엑터를 하나 받는 함수로 정의하여 사용하고 그 엑터에 해당 동작을 수행시킨다는 것으로 정의하면 이를 해결할 수 있다. JumpCommand는 excute안에서 점프 대상을 직접 찾지않고 넘겨받은 엑터에 점프를 수행시키면 된다. 이를 호출하는 쪽에서 적절한 엑터를 넣으며 command.excute(actor)로 실행시키면 해당 엑터에 점프가 수행된다.

이러한 방법 외에 멤버 변수로 수행할 엑터 포인터를 넣어 구현할수도 있다. excute는 다시 매개변수가 없는것으로 하고 JumpCommand에서 actor*와 float jumpPower를 멤버로 가지도록 한다음 생성자에서 이를 초기화할 수 있도록 하자. 그러면 JumpCommand를 생성할 때 두 값을 지정하여 생성하고 이를 실행하면 해당 엑터가 해당 파워만큼 점프하게 된다. 이렇게 command 클래스에 멤버를 주어 여러 상태를 저장하고 사용할 수 있다.

 

Undo

Command 클래스에 관련된 추가적인 동작을 정의할수 도있다. Command에 Undo라는 추상 메서드를 하나 추가한다고 하자. 이 메서드는 excute에서 실행한 내용을 되돌리는 기능을 구현한다. 만약 엑터를 특정 위치로 이동시키는 MoveCommand가 있을때 멤버에서 이동할 엑터와, 이동할 위치를 가지고 추가로 이동전 위치를 저장할 변수도 추가한다. excute에서는 엑터의 위치를 이동전 위치에 저장하고 위동할 위치로 이동시킨다. Undo에서는 엑터를 이동전 위치로 이동시킨다. 이렇게 하면 해당 커맨드에서 수행한 excute를 취소할 수 있다.

이러한 Command 패턴은 수행했던 명령들을 저장하여 Undo와 Redo하는 기능을 구현하는데 적합하다. cntl + Z를 제공해야하는 에디터나 게임의 리플레이 기능들을 구현하고자 할때 모든 동작과 수행을 Command로 만들어 처리한다면 수행해왔던 Command들을 저장하는 것 만으로 이를 쉽게 구현 할 수 있을 것이다.

 

 

 

 

참고서적

게임 프로그래밍 패턴