OpenGL로 2D 플랫폼 게임만들기 - 2. 충돌체크1 AABB

장명훈·2023년 6월 3일
0

OpenGL 2D platform

목록 보기
2/4

sprite 두개를 만들어서 충돌체크를 해보자. stage에 두 사각형을 만들고 겹치면 색이 바뀌는 코드를 만들어보자. 두 sprite는 그려지는 모양(render)과 위치(init)이 다르므로 함수 오버로드를 했다. 나중에는 몬스터도 있고 아이템도 있고 그럴텐도 각 sprite마다 init()과 release(), render()를 몬스터, 아이템별로 각각 오버로딩해서 Stage클래스에서 호출할 생각으로 말이다.

class Stage
{
private:
	Sprite mPlayer;
	Sprite mGround;
//... 
}
class Sprite{
public : 
    void init();                // player 꺼
    void init(int yt);          // Ground꺼 
    
    void Render();              // player 꺼
    void Render(int x);         // Ground꺼 
    // ...
};

그렇게 해서 땅과 플레이어를 그렸다.

이제 두 sprite가 겹치면 색이 바뀌게 해보자. 충돌 의사코드는 다음과 같다.

bool CollideRect(Entity &ent, XMFLOAT2 &CollisionVec2)
{
		//개체 중 하나가 활성 상태가 아니라면 충돌이 일어나지 않는다.
		if (!active || !ent.GetActive())
				return false;

		// 축 정렬 경계 상자를 사용해 충돌을 검사한다.
		if ((GetCenterX() + edge.right >= ent.GetCenterX() + ent.GetEdge().left) 
		&& (GetCenterX() + edge.left <= ent.GetCenterX() + ent.GetEdge().right) 
		&& (GetCenterY() + edge.bottom >= ent.GetCenterY() + ent.GetEdge().top) 
		&& (GetCenterY() + edge.top >= ent.GetCenterY() + ent.GetEdge().bottom)
		{
				// 충돌 벡터를 설정한다.
					CollisionVec2 = *ent.GetCenter() - *GetCenter();
					return true;
		}

		return false; // 충돌 하지 않음.
}

중심은 (mPos.x, g_Extern.WINDOWSIZE_HEIGHT - mPos.y) 이다. 그래픽, 축으로 보면 edge.right는 선인데 그냥 x좌표 비교하면 될듯 하다. edge.right 는 mSize.x / 2

bool Sprite::Collide(Sprite& other)
{
	// 축 검사해서 겹치면 
	if ((mPos.x + mSize.x / 2 >= other.mPos.x - other.mSize.x / 2)
		&& (mPos.x - mSize.x / 2 <= other.mPos.x + other.mSize.x / 2)
		&& (mPos.y - mSize.y / 2 <= other.mPos.y + other.mSize.y / 2)	// bottom < other.top (일반 좌표)
		&& (mPos.y + mSize.y / 2 >= other.mPos.y - other.mSize.y / 2))
	{
		return true;
	}
	return false; // 충돌 하지 않음.
}

좌표계가 어떻게 생겼는진 모르겠지만 player의 색이 항상 바뀌어있다. 해서 x축먼저 비교해보았다.

bool Sprite::Collide(Sprite& other)
{
	// 축 검사해서 겹치면 
	if ((mPos.x + mSize.x / 2 >= other.mPos.x - other.mSize.x / 2)
		&& (mPos.x - mSize.x / 2 <= other.mPos.x + other.mSize.x / 2))
	{
		return true;
	}
	return false; // 충돌 하지 않음.
}

이번엔 y축 비교를 해보자. y축은 우리가 알던 좌표계랑 좀 달라서 좀 애먹었다.

bool Sprite::Collide(Sprite& other)
{
	// 축 검사해서 겹치면 
	if ((mPos.x + mSize.x / 2 >= other.mPos.x - other.mSize.x / 2)
		&& (mPos.x - mSize.x / 2 <= other.mPos.x + other.mSize.x / 2)
		&& (mPos.y + mSize.y / 2 >= g_Extern.WINDOWSIZE_HEIGHT - (other.mPos.y + other.mSize.y / 2))	// bottom > other.top (일반 좌표)
		&& (mPos.y - mSize.y / 2 <= g_Extern.WINDOWSIZE_HEIGHT - (other.mPos.y - other.mSize.y / 2)))
	{
		return true;
	}
	return false; // 충돌 하지 않음.
}

하면서 느낀거는 좌표계를 그려보면서 하는게 가장 좋은 것 같다. 나중에 그림도 첨부하겠다.

0개의 댓글