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; // 충돌 하지 않음.
}
하면서 느낀거는 좌표계를 그려보면서 하는게 가장 좋은 것 같다. 나중에 그림도 첨부하겠다.