Collider ์ถฉ๋์ฒด๋ง๋ค ์์ด๋๋ฅผ ๊ณ ์ ๋ก ์ฃผ๋ ค๊ณ ํ๋๋ฐ ๋ง์ฝ ๊ฐ์ฒด๊ฐ ๋ณต์ฌ ๋์ด ์์ฑ๋๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น? ๊ธฐ๋ณธ ๋ณต์ฌ ์์ฑ์๋ ๊ทธ๋๋ก ๋ณต์ฌํด์ฃผ๊ธฐ ๋๋ฌธ์ ID๊ฐ ์ค๋ณต๋ ์ ์์. ์ด๋ ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ๊ณ ์ ํ๋ ๋ชฉํ์ ์๋ฐฐ๋๊ธฐ ๋๋ฌธ์ ๊น์ ๋ณต์ฌ ํ์๊ฐ ํ์ํ๋ค.
// Collider.h
class Object;
class Collider {
private:
static UINT nextID;
Object* owner;
Vec2 offsetPos;
Vec2 finalPos;
Vec2 scale;
UINT iID;
UINT col;
public:
Collider();
Collider(const Collider& _ori); // ๋ณต์ฌ์์ฑ์
~Collider();
Collider& operator = (Collider& _ori) = delete; // ๋์
์ฐ์ฐ์
void SetOffsetPos(Vec2 _pos) { offsetPos = _pos; }
void SetScale(Vec2 _scale) { scale = _scale; }
Vec2 GetOffsetPos() { return offsetPos; }
Vec2 GetScale() { return scale; }
Vec2 GetFinalPos() { return finalPos; }
Object* GetObj() { return owner; }
UINT GetID() { return iID; }
void finalUpdate();
void render(HDC _hdc);
// ์ถฉ๋ ์์ ํจ์ ์ถ๊ฐ
void OnCollision(Collider* _other);
void OnCollisionEnter(Collider* _other);
void OnCollisionExit(Collider* _other);
friend class Object;
};
// Collider.cpp
Collider::Collider(const Collider& _ori)
: owner(nullptr)
, offsetPos(_ori.offsetPos)
, scale(_ori.scale)
, iID(nextID++)
{
}
๋์ ์ฐ์ฐ์ ๋ํ ๋ง์ด ์๋๊ธฐ ๋๋ฌธ์ ๊ธ์ง ์์ผ์ฃผ์ด์ผ ํ๋ค. (delete ํค์๋ ์ฌ์ฉ)
์ ๋ฒ ์๊ฐ์ ํ ๋๋ฅผ ์ง๋จ๋ค. ํค ๊ฐ์ ๋งคํ ํด์ผ ํ๋๋ฐ ํด๋น ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
// Collider.h
union COLLIDER_ID{
struct {
UINT leftID;
UINT rightID;
};
ULONGLONG ID;
};
// Collider.cpp
void ColliderManager::CollisionUpdateGroup(GROUP_TYPE _left, GROUP_TYPE _right)
{
Scene* currScene = SceneManager::Instance()->GetCurScene();
const vector<Object*>& vecLeft = currScene->GetGroupObject(_left);
const vector<Object*>& vecRight = currScene->GetGroupObject(_right);
map<ULONGLONG, bool>::iterator iter;
for (size_t i = 0; i < vecLeft.size(); ++i) {
if (nullptr == vecLeft[i]->GetCollider()) // ์ถฉ๋์ฒด๊ฐ ์๋ค๋ฉด
continue;
for (size_t j = 0; j < vecRight.size(); ++j) {
if (nullptr == vecRight[j]->GetCollider()
|| (vecLeft[i] == vecRight[j])) // ์ถฉ๋์ฒด๊ฐ ์๊ฑฐ๋ ๋ ์์ ์ด๋ผ๋ฉด
continue;
Collider* leftCol = vecLeft[i]->GetCollider();
Collider* rightCol = vecRight[j]->GetCollider();
// ๋ ์ถฉ๋์ฒด ์กฐํฉ ์์ด๋ ์์ฑ
COLLIDER_ID ID; // ์ ์ฒด 8๋ฐ์ดํธ (longlong)
ID.leftID = leftCol->GetID(); // ๊ฐ๊ฐ 4๋ฐ์ดํธ
ID.rightID = rightCol->GetID();
iter = mapColInfo.find(ID.ID);
if (mapColInfo.end() == iter) {
// ๋ฑ๋ก์กฐ์ฐจ ๋์ง ์์๋ ๊ฒฝ์ฐ๋ ๋ฑ๋กํด์ผ ํจ(์ถฉ๋ํ์ง ์์๋ค)
mapColInfo.insert(make_pair(ID.ID, false));
iter = mapColInfo.find(ID.ID);
}
if (IsCollision(leftCol, rightCol)) {
// ํ์ฌ ์ถฉ๋ ์ค์ด๋ค
if (iter->second) {
// ์ด์ ์๋ ์ถฉ๋ํ๊ณ ์์๋ค - ์ถฉ๋ ์ค
leftCol->OnCollision(rightCol);
rightCol->OnCollision(leftCol);
}
else {
// ์ด์ ์๋ ์ถฉ๋ํ์ง ์์๋ค - ๋ง ์ถฉ๋ํจ
leftCol->OnCollisionEnter(rightCol);
rightCol->OnCollisionEnter(leftCol);
iter->second = true;
}
}
else { // ํ์ฌ ์ถฉ๋ํ๊ณ ์์ง ์๋ค.
if (iter->second) {
// ์ด์ ์๋ ์ถฉ๋ํ๊ณ ์์๋ค - ์ถฉ๋์์ ๋ ๋๊ฒ.
leftCol->OnCollisionExit(rightCol);
rightCol->OnCollisionExit(leftCol);
iter->second = false;
}
}
}
}
}
bool ColliderManager::IsCollision(Collider* _leftCol, Collider* _rightCol)
{
// ์ถฉ๋์ฒด์ ์ต์ข
์์น ์ป์ด์์ผ ํจ.
Vec2 leftPos = _leftCol->GetFinalPos();
Vec2 leftScale = _leftCol->GetScale();
Vec2 rightPos = _rightCol->GetFinalPos();
Vec2 rightScale = _rightCol->GetScale();
if (abs(rightPos.x - leftPos.x) < (leftScale.x + rightScale.x) / 2.f
&& abs(rightPos.y - leftPos.y) < (leftScale.y + rightScale.y) / 2.f) {
return true;
}
return false;
}
union์ ์ค๋ช ์ ์๋์ ํฌ์คํ ์ ์ฐธ๊ณ ํ๋๋ก ํ์.
https://velog.io/@commi1106/C-Union-%EA%B3%B5%EC%9A%A9%EC%B2%B4
[C++] Union (๊ณต์ฉ์ฒด)
๊ณต์ฉ์ฒด(union)๋ ๊ตฌ์กฐ์ฒด(struct)์ ๊ฑฐ์ ๋์ผํ์ง๋ง ๋ชจ๋ ๋ฉค๋ฒ ๋ณ์๊ฐ ํ๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ณต์ ํ๋ค๋ ์ ์ด ๋ค๋ฆ ๋๋ค.
velog.io
์ถฉ๋ํ๊ณ ์๋ ์ค์ธ์ง, ๋ง ์ถฉ๋ํ์๋์ง, ์ถฉ๋์ด ๋๋ฌ๋์ง์ ๋ฐ๋ผ์ ๊ฐ ์ค๋ธ์ ํธ์ ์ถฉ๋์ฒด์๊ฒ ์๋ ์ค๋ธ์ ํธ์์ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด์ค๋ค. ์ด๋ ๋งต์ ๋ฑ๋ก๋์ง ์์๋ค๋ ๊ฒ์ ์ด์ ํ๋ ์์ ์ถฉ๋ํ์ง ์์, ์ฆ ํ์ฌ ํ๋ ์์์ ์ฒ์ ์ผ์ด๋๋ ์ถฉ๋ ์ด๋ฒคํธ๋ก ๋งต์ ๋ฑ๋กํ๋ ์์ (insert)์ ์ํํ์ฌ์ผ ํ๋ค.
๋ง์ฝ ํ์ฌ ํ๋ก๊ทธ๋จ์์ ์ถฉ๋ํ๋ฉด ๊ทธ ์ถฉ๋๋ฐ์ค์ ์์ ๋ณ๊ฒฝํ๊ณ ์ ํ๋ค๋ฉด ์๋์ ์ฝ๋๋ฅผ ์ง์ฃผ๋ฉด ๋๋ค.
// Collider.cpp
void Collider::render(HDC _hdc)
{
// ์ถ๊ฐ ์์ญ //
PEN_TYPE pen = PEN_TYPE::GREEN;
if (col)
pen = PEN_TYPE::RED;
//////////////
SelectGDI p(_hdc, pen);
SelectGDI b(_hdc, BRUSH_TYPE::HOLLOW);
Rectangle(_hdc
, (int)(finalPos.x - scale.x / 2.f)
, (int)(finalPos.y - scale.y / 2.f)
, (int)(finalPos.x + scale.x / 2.f)
, (int)(finalPos.y + scale.y / 2.f));
}
์๋์ ๊ฐ์ด ์ถฉ๋ํ๋ฉด ๊ทธ๋ฆฐ์์ ๋ ๋๋ก ๋ฐ๋๋ ์ถฉ๋ ์์ญ์ ํ์ธํ ์ ์๋ค.
๋นผ ๋จน์ ์ฝ๋๊ฐ ์์ ์ ์์์ผ๋ก ์๋์ ๊นํ๋ธ ์ปค๋ฐ์ ๋น๊ตํด์ ์์ฑํ๋๋ก ํด๋ผ.
์๊ฐํด๋ณด์.
๊ฐ์ ์ถฉ๋์ด ๋ฐ์ํ์๋๋ผ๋ ํด์ผ ํ ์ผ์ ๋ค๋ฅด๋ค. ์๋ฅผ ๋ค์ด player-monster๊ฐ์ ์ถฉ๋ ์ฒ๋ฆฌ์ธ ๊ฒฝ์ฐ player๋ hp๊ฐ์, monster๋ ๋๋ฆฌ๋ ๋ชจ์ ๋ฑ ํด์ผ ํ ์ผ์ด ๋ค๋ฅด๋ค. ์ด๊ฑธ ์์ ๋ฐ์์ ํด์ผ ํ ๊น? ๊ทธ๋ฌ๋ฉด ๋๋ฌด ๋ณต์กํด์ง๋ค.
์ ๋ต์ ๋คํ์ฑ์ ์ด์ฉํ์. ์ถฉ๋์ฒด๋ ์ถฉ๋์ ์์ ํ๊ณ ์๋ ์ค๋ธ์ ํธ ํด๋์ค๋ฅผ ์์ธํ๊ฒ๋ ๋ชจ๋ฅด๋ ์ถฉ๋์ฒด ๋ด๋ถ์์ ์ค๋ธ์ ํธ๋ฅผ ๊ฐ๋ฅดํฌ ์๋ ์๋ค. (์์์์ owner๊ฐ์ฒด)
์ถฉ๋์ฒด ๋ด๋ถ์์ ์ถฉ๋ ์ด๋ฒคํธ๋ฅผ ๊ฐ์ํจ์๋ก ๋ง๋ค์ด ๋จ์ผ๋ฉด ์ถฉ๋์ฒด๋ ์ค๋ธ์ ํธ์ ์ด๋ฅผ ์๋ ค์ฃผ๊ณ ์์์ ์ฒ๋ฆฌํ๋๋ก ํ๋ฉด ๋์ง ์์๊น?
Object.h์ ์๋์ ์ฝ๋๋ฅผ ๋ฃ๋๋ก ํ์
ํด๋น ์ ์๋ ์์ ํด๋์ค์์ ํ ๊ฒ์ด๋ค.
์ด๋ ๊ฒ ํด ๋์ผ๋ฉด ์๋์ ์ฝ๋์ฒ๋ผ ์ถฉ๋์ฒด์์ ์ด๋ฒคํธ์ ๋ฐ๋ผ ์ค๋ธ์ ํธ์ ์๋ ค์ฃผ๋ฉด ๋ ๊ฒ์ด๋ค.
void Collider::OnCollision(Collider* _other)
{
owner->OnCollision(_other);
}
void Collider::OnCollisionEnter(Collider* _other)
{
++col;
owner->OnCollisionEnter(_other);
}
void Collider::OnCollisionExit(Collider* _other)
{
--col;
owner->OnCollisionExit(_other);
}
์ด์ ํด๋น ์ค๋ธ์ ํธ ๊ฐ์ฒด์์ ์ฌ์ฉํ ์ถฉ๋ ์ด๋ฒคํธ์ ๋ํ ํจ์๋ฅผ ์ ์ํ๋ฉด ๋๋ค.
// Monster.h
virtual void OnCollisionEnter(Collider* _other); // ์ถ๊ฐ
// Monster.cpp
void Monster::OnCollisionEnter(Collider* _other)
{
Object* otherObj = _other->GetObj();
// if (otherObj->GetName() == L"Missile") {
// ์ถฉ๋ ์๋๊ฐ ๋ฏธ์ฌ์ผ์ธ ๊ฒฝ์ฐ ๋ ์์ ์ ์ญ์
//}
}
์์ ์ฝ๋์์ ๋ฌธ์ ๊ฐ ๋๋ ๊ฒ์ด ์๋ค.
์ค๋ธ์ ํธ๋ฅผ ์ญ์ ํ๊ฒ ๋๋ ๊ฒฝ์ฐ ํด๋น ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ทผํ ์ ์๋๋ก ํด์ผ ํ๋ค. ์ฆ ์ฐธ์กฐํ๊ณ ์๋ ์ ๋คํํ ์ฃฝ์๋ค๋ ์ฌ์ค์ ์๋ ค์ผ ํ๋๋ฐ ๋ชจ๋ ์ค๋ธ์ ํธ๋ฅผ ์ด๋ป๊ฒ ์กฐ์ฌํ๊ณ , ์ฝ๋ฉํ ๋๋ ์ญ์ ๋ ์ค๋ธ์ ํธ๋ฅผ ๊ฑด๋ค์ผ๊น ๋ด ๊ฑฑ์ ํ๊ฒ ๋๋ค.
์ญ์ ๋ฅผ ์ด๋ป๊ฒ ํด์ผํ๋๊ฐ?, ์ฌ ๋ณ๊ฒฝ๋ ๋ฌธ์ (A์ฌ updateํ๋๋ฐ B์ฌ์ผ๋ก ์ฒด์ธ์ง ๋๋ฉด ?)
ํค ์ด๋ฒคํธ ๋งํ ๋๋ ์๊ธฐ ํ์ง๋ง ์ด๋ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ชจ๋ ํ๋ ์์ ๋์ผํ๊ฒ ์ ์ฉ๋์ด์ผ ํ๋ค. ๊ฐ์ ํ๋ ์ ์ฌ๊ฑด์์๋ ๋ค๋ฅด๊ฒ ๋ฐ์ ๋ค์ฌ์ง ์๊ฐ ์๊ธฐ์ ์ค์ํ ์ด๋ฒคํธ๋ฅผ ํ์ ๋จ์๋ก ๋๊ธฐํ ํด์ผ ํ๋ค. ( = ์ง์ฐ์ฒ๋ฆฌ )
๋ค์ ์๊ฐ์ ์ค๋ธ์ ํธ๊ฐ "๋ ์ฃฝ์ฌ์ฃผ์ธ์" ํด๋ ๋ฐ๋ก ์ฃฝ์ด์ง ์๊ณ ๋ชจ๋ ์ ๋ฐ์ดํธ๊ฐ ๋ค ๋๊ณ ๋ค์ ์ ๋ฐ์ดํธ์์ ์ ์ฉํ ๊ฒ์ด๋ค. ์ด๊ฒ์ด Event๋งค๋์ .
https://github.com/MiyeongEom/GameBasic/commit/7a1699528ebab8de4cd97e2c4d05ba6f2f3d1594
~Collider(3) · MiyeongEom/GameBasic@7a16995
MiyeongEom committed Jun 9, 2024
github.com
'๐ค Study > winAPI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[winAPI 16] Scene & Object (1) | 2024.06.10 |
---|---|
[winAPI 15] Event Manager (1) | 2024.06.10 |
[winAPI 13] Collider(2) (1) | 2024.06.08 |
[winAPI 12] Collider(1) (0) | 2024.06.06 |
[winAPI 11] Resource Manager (0) | 2024.06.06 |