지금까지 만든 구현한 맵 로드와 기본 액터 생성 구조 위에 실제 소코반 게임 규칙을 추가했다.
핵심은 두 가지
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. 박스 밀기 규칙
플레이어가 이동하려는 위치에 박스가 있다면, 박스를 한 칸 더 밀 수 있는지 확인해야 한다.
먼저 박스가 이동할 다음 위치를 계산, 그 우취에 벽이나 다른 박스가 있으면 밀 수 없다. 이동할 수 있는 위치라면 박스를이동시키고, 플레이어도 원래 박스가 있던 칸으로 이동한다.
박스를 이동시킨 다음에는 CheckGameClear()를 호출해 박스와 타겟의 위치가 일치하는지 확인한다. 모든 박스가 타겟에 놓였다면 게임 클리어 상태로 변경한다.
6. 게임 클리어 판정
CheckGameClear()에서는 액터 목록에서 Box와 Target을 구분하고, 좌표가 일치하는 박스와 타겟의 개수를 계산한다.
actor->IsTypeOf<Box>();
actor->IsTypeOf<Target>();
7. 빌드 시 Assets 복사
맵 파일을 실행 경로 기준 상대 경로로 읽기 때문에, 실행 파일이 있는 위치에서 Assets폴더를 찾을 수 있어야한다.
빌드할 때 Assets폴더를 출력 경로에 복사하도록 SokobanGame.vcxproj에 PreBuildEvent를 추가한다.
xcopy ..\Assets\* $(OutDir)..\Assets\ /e /y /i
이 설정을 통해 빌드 후 실행 시 맵 파일을 찾도록 한다.
'엔진프레임워크 만들기' 카테고리의 다른 글
| 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 |



























