프로그래밍/Win32 API
##3. 충돌체크 / 추상팩토리패턴 / 컨테이터 순차접근 / 문자열출력
hscho00
2020. 8. 17. 12:30
LateUpdate()
모든 개체의 Update()를 완료 후, 변경된 값을 토대로
상태를 변경할 필요가 있을 때 사용
RECT 충돌체크
BOOL IntersectRect(
LPRECT lprcDst,
const RECT *lprcSrc1,
const RECT *lprcSrc2
);
원형 충돌체크
두 중심 사이의 거리가 두 반지름의 합보다 작으면 충돌
bool CCollisionMgr::CheckCircle(const CObj& _obj1, const CObj& _obj2)
{
float fX = abs(_obj1.Get_Info().fX - _obj2.Get_Info().fX);
float fY = _obj1.Get_Info().fY - _obj2.Get_Info().fY;
float fRad = (float)((_obj1.Get_Info().iWidth + _obj2.Get_Info().iHeight) >> 1);
if (fRad * fRad > fX * fX + fY * fY)
return true
return false;
}
CollisionMgr
// CCollisionMgr.h
// ...
class CCollisionMgr
{
public:
CCollisionMgr();
~CCollisionMgr();
public:
static void SetDead_Rect(vector<CObj*>& _v1, vector<CObj*>& _v2);
static void SetDead_Circle(vector<CObj*>& _v1, vector<CObj*>& _v2);
private:
static bool CheckCircle(const CObj& _obj1, const CObj& _obj2);
};
// CCollisionMgr.cpp
// ...
void CCollisionMgr::SetDead_Rect(vector<CObj*>& _v1, vector<CObj*>& _v2)
{
RECT rc = {};
for (auto& obj1 : _v1)
{
if (obj1->IsDead())
continue;
for (auto& obj2 : _v2)
{
if (obj2->IsDead())
continue;
if (IntersectRect(&rc, &obj1->Get_Rect(), &obj2->Get_Rect()))
{
obj1->Set_Dead(true);
obj2->Set_Dead(true);
}
}
}
}
void CCollisionMgr::SetDead_Circle(vector<CObj*>& _v1, vector<CObj*>& _v2)
{
for (auto& obj1 : _v1)
{
if (obj1->IsDead())
continue;
for (auto& obj2 : _v2)
{
if (obj2->IsDead())
continue;
if (CheckCircle(*obj1, *obj2))
{
obj1->Set_Dead(true);
obj2->Set_Dead(true);
}
}
}
}
// CMainGame.cpp
//...
void CMainGame::LateUpdate()
{
CCollisionMgr::SetDead_Rect(m_vecObj[OBJ::ID::MONSTER], m_vecObj[OBJ::ID::BULLET]);
for (int i = 0; i < OBJ::ID_END; ++i)
{
for (auto& pObj : m_vecObj[i])
{
if (pObj->IsDead())
continue;
pObj->LateUpdate();
}
}
// ...
}
추상 팩토리 패턴
구체적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 개체들의 조합을 만드는 인터페이스를 제공하는 패턴
> 관련성 있는 여러 종류의 개체를 일관된 방식으로 생성하는 경우에 유용
> 생성 방법을 알고 있는 개체를 매개변수를 넘겨받음으로써 생성할 개체의 유형을 달리한다
// AbstractFactory.h
#pragma once
class CObj;
template<typename T>
class CAbstractFactory
{
public:
static CObj* Create()
{
CObj* pObj = new T;
pObj->Init();
return pObj;
}
static CObj* Create(float _x, float _y)
{
CObj* pObj = new T;
pObj->Init();
pObj->Set_Pos(_x, _y);
return pObj;
}
};
// MainGame.cpp
// ...
void CMainGame::Init()
{
// ...
CObj* pPlayer = CAbstractFactory<CPlayer>::Create();
// ...
}
여기서는 생성 방법을 알고 있는 개체(Factory)를 만들지 않고 간단하게 매개변수를 통해서만 구분하였음
컨테이너 순차 접근
// MainGame.h
// ...
vector<CObj*> m_vecObj[OBJ::ID_END];
// MainGame.cpp
//...
void CMainGame::Update()
{
for (int i = 0; i < OBJ::ID_END; ++i)
{
for (auto& pObj : m_vecObj[i])
{
pObj->Update();
}
}
}
문자열 출력
BOOL TextOutA(
HDC hdc,
int x,
int y,
LPCSTR lpString,
int c
);
// MainGame.cpp
// ...
void CMainGame::Render()
{
// ...
TCHAR szBuff[16] = L"";
swprintf_s(szBuff, L"Bullet: %d", m_iBulletAliveCnt);
TextOut(m_hDC, 50, 50, szBuff, lstrlen(szBuff));
// ...
}