728x90
1. 상태 패턴 정의
- 객체의 내부 상태에 따라 스스로 행동을 변경할 수 있게 허가하는 패턴으로, 이렇게 하면 객체는 마치 자신의 클래스를 바꾸는 것처럼 보입니다.
2. 유한 상태 기계 ( FSM : Finite State Machine )
- 가질 수 있는 '상태'가 한정된다
- 합 번에 '한 가지' 상태만 될 수 있다.
- '입력'이나 '이벤트'가 기계에 전달된다.
- 각 상태에는 입력에 따라 다음 상태로 바뀌는 '전이'가 있다.
- 엄격하게 제한된 구조를 강제함으로써 복잡하게 얽힌 코드를 정리할 수 있게 한다.
- 미리 정해놓은 여러 상태와 현재 상태 하나, 하드 코딩되어 있는 전이만 존재
3. 상태 인터페이스 구현
// 상태 인터페이스
class HeroineState
{
public:
virtual ~HeroineState() {}
virtual HeroineState* HandleInput( Heroine& InHeroine, INPUT InInput ) {}
// 상태 입장.
virtual void Enter( Heroine& InHeroine ) {}
// 상태 퇴장
virtual void Exit( Heroine& InHeroine ) {}
};
4. 상태별 클래스
// 상태별 클래스
class DuckingState : public HeroineState
{
public:
virtual HeroineState* HandleInput( Heroine& InHeroine, INPUT InInput ) override
{
if ( InInput == INPUT::RELEASE_DOWN )
return new StandingState();
}
virtual void Enter( Heroine& InHeroine ) override
{
// 상태 입장 시 실행될 함수들
InHeroine.SetGraphics( STATE_IMAGE::IMAGE_DUNCKING );
}
virtual void Exit( Heroine& InHeroine ) override
{
// 상태 퇴장 시 실행될 함수들
}
};
class StandingState : public HeroineState
{
public:
virtual HeroineState* HandleInput( Heroine& InHeroine, INPUT InInput ) override
{
if ( InInput == INPUT::PRESS_DOWN )
return new DuckingState();
// 현재 상태 유지
return nullptr;
}
virtual void Enter( Heroine& InHeroine ) override
{
// 상태 입장 시 실행될 함수들
InHeroine.SetGraphics( STATE_IMAGE::IMAGE_STAND );
}
virtual void Exit( Heroine& InHeroine ) override
{
// 상태 퇴장 시 실행될 함수들
}
};
5. 동작 상태 위임
class Heroine
{
private:
HeroineState* State;
public:
virtual void HandleInput( INPUT InInput )
{
HeroineState* state = State->HandleInput( *this, InInput );
if ( state != nullptr )
{
// 기존 상태 퇴장 함수 호출
State->Exit( *this );
delete State;
State = state;
// 새로운 상태의 입장 함수 호출
State->Enter( *this );
}
}
void SetGraphics( STATE_IMAGE InStateImage );
};
6. 병행 상태 기계
// 병행 상태 기계
class Heroine
{
private:
// 캐릭터 상태
HeroineState* State;
// 장비 상태
HeroineState* Equipment;
public:
virtual void HandleInput( INPUT InInput )
{
// 나누어진 상태 모두에게 전달
HeroineState* state = State->HandleInput( *this, InInput );
HeroineState* equipment = Equipment->HandleInput( *this, InInput );
//....
}
};
- 유한 상태 기계 방식을 이용한 경우, 두 종류의 상태를 위해서는 N*M개의 상태가 필요하다.
- 상태 기계 둘로 나누어 사용할 경우 N+M개의 상태만 있으면된다.
7. 계층형 상태 기계
// 상위 상태
class OnGroundState : public HeroineState
{
public:
virtual HeroineState* HandleInput( Heroine& InHeroine, INPUT InInput ) override
{
if ( InInput == INPUT::RELEASE_DOWN )
{
return new StandingState();
}
else if ( InInput == INPUT::PRESS_DOWN )
{
//..
}
}
};
// 하위 상태
class DuckingState : public OnGroundState
{
public:
virtual HeroineState* HandleInput( Heroine& InHeroine, INPUT InInput ) override
{
if ( InInput == INPUT::RELEASE_DOWN )
{
return new StandingState();
}
else
{
// 따로 입력을 처리하지 않고, 상위 상태로 보낸다.
OnGroundState::HandleInput( InHeroine, InInput );
}
}
};
- '땅 위에 있는' , '바다 안에 있는' 상태 등 특정 상태를 상위 클래스로 정의해 처리하는 것을 계층형 상태 기계라고 한다.
- 어떤 상태는 상위 상태를 가질 수 있고, 그 경우 그 상태 자신은 하위 상태가 된다.
- 이벤트가 들어올 때 하위 상태에서 처리하지 않으면, 상위 상태로 넘긴다.
반응형
'Design Pattern > 게임 프로그래밍 패턴' 카테고리의 다른 글
[Design Pattern] 업데이트 메서드 패턴 (0) | 2022.08.01 |
---|---|
[Design Pattern] 게임 루프 패턴 (0) | 2022.07.31 |
[Design Pattern] 싱글턴 패턴 (0) | 2022.07.30 |
[Design Pattern] 프로토타입 패턴 (0) | 2022.07.30 |
[Design Pattern] 관찰자 패턴 (0) | 2022.07.30 |