주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다.
2D 기반 다양한 충돌 체크 방법
- 횡스크롤 기반 2D 게임이든, 3D이지만 탑뷰 시점 고정인 게임이든, 2차원 평면에서의 충돌 판정을 내는 방법은 여러 가지 있다.
픽셀 충돌
- sprite와 같은 2차원 평면으로 오브젝트나 캐릭터들이 표현된다면, 각 sprite가 가지는 픽셀들이 있을 것이다.
- 이 경우, 두 sprite의 충돌 판정은 각 sprite의 픽셀들중 겹치는 위치에 존재하는 픽셀이 있는지 확인하면 된다.
- 예를 들어 spriteA의 한 픽셀이 (3, 5)위치에 있고, spriteB의 한 픽셀이 (3, 5)에 있다면 이를 “충돌했다”라고 판단하고, 충돌 이벤트를 발동시킨다.
- 장점: 복잡한 도형으로 만들어진 충돌 영역이더라도 충돌 처리가 가능
- 단점: sprite를 이루는 픽셀이 많아질수록 부하가 큼
도형 충돌: 원 충돌
- 대부분의 충돌은 단순화된 도형을 통해 처리한다. 그 중 두 원 사이의 충돌은 비교적 간단하다.
- 중학교 때인가? 배운 개념을 사용하면 된다. 두 원의 중점 거리를 d라고 하고, 각 원의 반지름을 r1, r2라고 했을 때 r1 + r2 < d 인 경우, 충돌했다고 판정하면 된다.
- 충돌 판정이 쉽고 빠르기 때문에 많은 게임에서 원 모양 스킬이 자주 나오는 이유도 여기에 있다. 어찌어찌 잘 써보자
- 장점: 쉽고 빠르게 충돌 판정 가능
- 단점: 원들 사이에서만 구하는 공식이므로, 조금 제한적임(단점같지 않은 단점)
도형 충돌: 회전없는 사각형 충돌(AABB충돌)
- 길쭉한 투사체를 날린다거나, 직사각형 장판을 까는 등 사각형은 원만큼은 아니더라도 꽤 사용한다. 게다가 대부분의 sprite들이 사각형의 형태를 하고 있는 것을 보면 횡스크롤 2d게임 입장에서는 정말 많이 쓸 것이다.
- 회전 없는 사각형끼리의 충돌은 AABB라고, Axis-Aligned Bounding Box의 약자로 각 오브젝트의 두 꼭짓점을 이용해 충돌을 판정한다.
- AABB의 좌상단 꼭짓점을 min, 우하단 꼭짓점을 max라고 했을 때 한쪽 사각형의 max.x < min.x 또는 min.x > max.x를 만족한다면 x축에서 두 사각형은 만나지 않는다는 것을 알 수 있습니다.
struct Vec2
{
double x;
double y;
};
struct AABB
{
Vec2 min;
Vec2 max;
};
bool AABB_to_AABB(AABB a, AABB b)
{
if (a.max.x < b.min.x || a.min.x > b.max.x) return false;
if (a.max.y < b.min.y || a.min.y > b.max.y) return false;
return true;
}