충돌 처리는 객체 간의 상호작용을 감지하고, 그 결과를 처리하는 게임 개발의 중요한 요소입니다. 일반적으로 두 가지 방식으로 나뉩니다:
1. 충돌 감지 (Collision Detection): 객체들이 충돌했는지 확인하는 단계.
2. 충돌 반응 (Collision Response): 충돌 시의 반응을 처리하는 단계. 예를 들어, 객체를 튕겨내거나, 이동을 막는 등의 작업.
BoxCollider 클래스와 GetRect 함수를 활용.class Player : public FlipbookActor
{
using Super = FlipbookActor;
public:
Player();
virtual ~Player() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Render(HDC hdc) override;
virtual void OnComponentBeginOverlap(Collider* collider, Collider* other) override;
virtual void OnComponentEndOverlap(Collider* collider, Collider* other) override;
private:
void TickGravity();
void AdjustCollisionPos(BoxCollider* b1, BoxCollider* b2);
public:
Flipbook* _flipbookUp = nullptr;
Flipbook* _flipbookDown = nullptr;
Flipbook* _flipbookLeft = nullptr;
Flipbook* _flipbookRight = nullptr;
};
분석:
Player 클래스는 FlipbookActor를 상속받아 생성된 플레이어 객체입니다.OnComponentBeginOverlap: 충돌 시작 시 호출.OnComponentEndOverlap: 충돌 종료 시 호출.AdjustCollisionPos: 충돌 발생 시 객체 위치를 조정하는 핵심 함수._flipbookUp, _flipbookDown 등은 플레이어의 방향에 따라 애니메이션을 설정하기 위한 Flipbook 객체.Player::Player()
{
_flipbookUp = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveUp");
_flipbookDown = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveDown");
_flipbookLeft = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveLeft");
_flipbookRight = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveRight");
// 플레이어에게 카메라 넣어주기
CameraComponent* camera = new CameraComponent();
AddComponent(camera);
}
분석:
ResourceManager에서 불러옵니다.CameraComponent를 생성하여 플레이어의 위치를 중심으로 카메라가 이동하도록 설정.void Player::Tick()
{
Super::Tick();
float deltaTime = GET_SINGLE(TimeManager)->GetDeltaTime();
if (GET_SINGLE(InputManager)->GetButton(KeyType::W))
{
_pos.y -= 200 * deltaTime;
SetFlipbook(_flipbookUp);
}
else if (GET_SINGLE(InputManager)->GetButton(KeyType::S))
{
_pos.y += 200 * deltaTime;
SetFlipbook(_flipbookDown);
}
else if (GET_SINGLE(InputManager)->GetButton(KeyType::A))
{
_pos.x -= 200 * deltaTime;
SetFlipbook(_flipbookLeft);
}
else if (GET_SINGLE(InputManager)->GetButton(KeyType::D))
{
_pos.x += 200 * deltaTime;
SetFlipbook(_flipbookRight);
}
}
분석:
W, S, A, D 키는 각각 위, 아래, 왼쪽, 오른쪽으로 이동.deltaTime을 곱하여 프레임 독립적인 속도로 처리.void Player::OnComponentBeginOverlap(Collider* collider, Collider* other)
{
BoxCollider* b1 = dynamic_cast<BoxCollider*>(collider);
BoxCollider* b2 = dynamic_cast<BoxCollider*>(other);
if (b1 == nullptr || b2 == nullptr)
{
return;
}
AdjustCollisionPos(b1, b2);
}
분석:
Collider 객체를 BoxCollider로 변환. 변환에 실패하면 nullptr 반환.AdjustCollisionPos 함수로 충돌 처리.void Player::AdjustCollisionPos(BoxCollider* b1, BoxCollider* b2)
{
RECT r1 = b1->GetRect();
RECT r2 = b2->GetRect();
Vec2 pos = GetPos();
RECT intersect = {};
if (::IntersectRect(&intersect, &r1, &r2))
{
int32 w = intersect.right - intersect.left;
int32 h = intersect.bottom - intersect.top;
if (w > h)
{
if (intersect.top == r2.top)
{
pos.y -= h;
}
else
{
pos.y += h;
}
}
else
{
if (intersect.left == r2.left)
{
pos.x -= w;
}
else
{
pos.y += w;
}
}
}
SetPos(pos);
}
분석:
RECT 객체를 통해 두 충돌 박스의 교차 영역(intersect)을 계산.w)과 높이(h)를 비교하여 충돌 방향을 결정:pos.y를 조정.pos.x를 조정.RECT BoxCollider::GetRect()
{
Vec2 pos = GetOwner()->GetPos();
Vec2 size = GetSize();
RECT rect =
{
(int32)(pos.x - (size.x / 2)),
(int32)(pos.y - (size.y / 2)),
(int32)(pos.x + (size.x / 2)),
(int32)(pos.y + (size.y / 2))
};
return rect;
}
분석:
pos)와 크기(size)를 기반으로 충돌 박스의 RECT를 반환.pos.x - (size.x / 2)pos.y - (size.y / 2)pos.x + (size.x / 2)pos.y + (size.y / 2)