지금까지 만든 구현한 맵 로드와 기본 액터 생성 구조 위에 실제 소코반 게임 규칙을 추가했다.
핵심은 두 가지
1. 플레이어의 이동 가능 여부를 GameLevel에 질의하는 구조
2. 박스와 타겟의 위치를 비교해 게임 클리어를 판정하는 구조
1. 주요 변경점
플레이어 이동 규칙 추가
1. 벽에 막히는가
2. 박스를 밀 수 있는가?
3. 박스 뒤에 다른 박스나 벽이 있는가?
4. 이미 게임이 클리어된 상태인가?
2. 이동 판정 인터페이스
플레이어가 레벨의 구체적인 내부 구조를 직접 알지 않도록 ICanPlayerMove 인터페이스를 추가했다.
class ICanPlayerMove
{
public:
virtual ~ICanPlayerMove() = default;
virtual bool CanMove(
const Vector2& playerPosition,
const Vector2& nextPosition
) = 0;
};
GameLevel 은 이 인터페이스를 상속한다.
class GameLevel : public Level, public ICanPlayerMove
{
public:
virtual bool CanMove(
const Vector2& playerPosition,
const Vector2& nextPosition
) override;
};
Player : 이동을 요청하고 실제 위치를 변경
GameLevel : 벽, 박스, 타겟 등 게임 규칙 판단
ICanPlayerMove : 플레이어가 레벨에 이동 가능 여부를 요청하기 위한 계약
플레이어가 모든 충돌 규칙을 직접 처리하지 않기 때문에, 이후 규칙이 변경되어도 GameLevel중심으로 수정할 수 있다.
3. Player 이동 방식 변경
그 후 플레이어의 오너 레벨을 ICanPlayerMove로 변환해 이동 가능 여부를 확인한다.
std::shared_ptr<ICanPlayerMove> movableLevel =
std::dynamic_pointer_cast<ICanPlayerMove>(GetOwner());
if (movableLevel != nullptr)
{
if (movableLevel->CanMove(position, newPosition) == true)
{
SetPosition(newPosition);
}
}
4. GameLevel의 이동 규칙
GameLevel::CanMove()는 플레이어가 이동하려는 위치를 검사한다.
1. 게임이 클리어되어있는지 확인
2. 이동 위치에 박스가 있는지 확인
3. 박스가 있다면 박스 뒤에 위치 확인
4. 박스 뒤에 다른 박스나 벽이 있으면 이동 실패
5. 이동이 가능하면 박스를 한 칸 이동
6. 박스 이동 후 클리어 여부 확인
7. 이동 위치에 박스가 없다면 벽만 확인
5. 박스 밀기 규칙
플레이어가 이동하려는 위치에 박스가 있다면, 박스를 한 칸 더 밀 수 있는지 확인해야 한다.
'엔진프레임워크 만들기' 카테고리의 다른 글
| C++ 엔진프레임워크 - 11 맵 데이터 로드 및 기본 액터 생성 (0) | 2026.09.23 |
|---|---|
| C++ 엔진프레임워크 - 10 커스텀 타입 시스템(RTTI) (0) | 2026.09.21 |
| C++ 엔진프레임워크 - 9 엔진설정 로드 시스템 (0) | 2026.09.15 |
| C++ 엔진프레임워크 - 8 2중 버퍼링 - 2 (0) | 2026.09.15 |
| C++ 엔진프레임워크 - 7 2중 버퍼링 (0) | 2026.09.10 |



























