๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ Development Study/๐Ÿ’ป Win32API

Collider Manager

by eazuooz 2022. 9. 30.

์˜ˆ์ œ :)

https://github.com/eazuooz/WindowAPI/commit/5a78f083e6fdf77aadc65469df0d379a68215599

 

Collision manger 2 · eazuooz/WindowAPI@5a78f08

Show file tree Showing 16 changed files with 149 additions and 35 deletions.

github.com

 

์ „ ์žฅ๊นŒ์ง€์—์„œ ์šฐ๋ฆฌ๋Š” ์ถฉ๋Œ์ฒด๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค.

๊ทธ๋Ÿผ ๊ฐ๊ฐ์˜ ์ œ์ž‘๋œ ์ถฉ๋Œ์ฒด๋กœ ์–ด๋–ป๊ฒŒ ์ถฉ๋Œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค„๊ฒƒ์ธ๊ฐ€?

์ถฉ๋Œ์ฒ˜๋ฆฌ๋ฅผ ๋„์™€์ค„ CollisionManager๋ฅผ ์ œ์ž‘ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

 

	class Scene;
	class Collider;
	class CollisionManager
	{
	public:
		static void Tick();
		static void LayerCollision(Scene* scene, eColliderLayer left, eColliderLayer right);
		static void ColliderCollision(Collider* left, Collider* right);
		static bool Intersect(Collider* left, Collider* right);

		static void clear();
		static void SetLayer(eColliderLayer left, eColliderLayer right, bool value);
		
	private:
		static WORD mMatrix[_COLLIDER_LAYER];
		static std::map<UINT64, bool> mCollisionInfomations;
	};

 

์ผ๋‹จ ์–ด๋–ค ์ถฉ๋Œ์ฒด ๋ผ๋ฆฌ ์ถฉ๋Œ์„ ํ•ด์ค˜์•ผ ํ• ์ง€ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ 2์ฐจ์› ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด Player 1๋ฒˆ ๊ณผ Monster 3๋ฒˆ์ด ์ถฉ๋Œ์„ ์„œ๋กœ ํ•ด์•ผํ•˜๋Š” ์กด์žฌ๋ผ๋ฉด

๋ฐฐ์—ด์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  1 2 3 4 5 6
1 true   true      
2   true true   true true
3     true true    
4       true true  
5         true true
6           true

๊ทธ๋ฆฌ๊ณ   ๋˜ํ•œ ์ž์„ธํžˆ๋ณด๋ฉด 1,3 ๊ณผ 3,1 ์ด ๊ฒฐ๋ก ์ ์œผ๋กœ ๋‘˜๋‹ค ๊ฐ™์€ ์ถฉ๋Œ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋–„๋ฌธ์— 

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฐ์‚ฐ์œผ๋กœ ๋‘์ˆ˜์˜ ํฌ๊ธฐ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ž‘์€ ์ˆซ์ž๋ฅผ row ์ชฝ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ

ํ•œ์ชฝ์—๋งŒ ํ‘œ์‹œํ•ด์ฃผ๊ธฐ๋กœ ํ•˜๊ฒ ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š” ๋Œ€๊ฐ์„ ์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ์ชฝ๋งŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉ๋  ๊ฒƒ์ด๋‹ค.

	void CollisionManager::SetLayer(eColliderLayer left, eColliderLayer right, bool value)
	{
		// ๋” ์ž‘์€ ์ˆซ์ž๋ฅผ ํ–‰(๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค)์œผ๋กœ, ๋” ํฐ ์ˆซ์ž๋ฅผ ์—ด(๋น„ํŠธ ์œ„์น˜)๋กœ
		UINT row = 0;
		UINT col = 0;

		UINT iLeft = (UINT)left;
		UINT iRight = (UINT)right;
		if (iLeft <= iRight)
		{
			row = (UINT)iLeft;
			col = (UINT)iRight;
		}
		else
		{
			row = (UINT)iRight;
			col = (UINT)iLeft;
		}

		if (value == true)
			mMatrix[row] |= (1 << col);
		else
			mMatrix[row] &= ~(1 << col);
	}

 

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ๋งคํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ•ด๋‹น ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ ์ˆœํšŒ ํ•˜๋ฉด์„œ ์ถฉ๋Œ์ฒด๋ฅผ ๋น„๊ตํ•ด์ค€๋‹ค.

	void CollisionManager::Tick()
	{
		Scene* scene = SceneManager::GetPlayScene();
		for (UINT row = 0; row < _COLLIDER_LAYER; row++)
		{
			for (UINT col = row; col < _COLLIDER_LAYER; col++)
			{
				if (mMatrix[row] & (1 << col))
				{
					LayerCollision(scene, (eColliderLayer)row, (eColliderLayer)col);
				}
			}
		}
	}

์ด์ œ ๊ฐ ๋ ˆ์ด์–ด์— ์ถ”๊ฐ€๋œ ์˜ค๋ธŒ์ ํŠธ๋“ค์„ ์ „๋ถ€ ๋ถˆ๋Ÿฌ์™€์„œ ๊ฐ์ž ์ถฉ๋Œ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

์„œ๋กœ ๊ฐ™์€ ์˜ค๋ธŒ์ ํŠธ์ด๊ฑฐ๋‚˜ ๊ฐ™์€ ๋ ˆ์ด์–ด๋ผ๋ฆฌ์˜ ์ถฉ๋Œ์ด๋ผ๋ฉด ์ถฉ๋Œ์—ฐ์‚ฐ์ด 2๋ฒˆ์ผ์–ด๋‚˜๊ธฐ ๋–„๋ฌธ์—

ํ•œ๋ฒˆ๋งŒ ์ถฉ๋Œํ•ด์ฃผ๋Š” ์˜ˆ์™ธ์ฒ˜๋ฆฌ๊ฐ€ ์ถ”๊ฐ€ ๋˜์–ด์žˆ๋‹ค.

	void CollisionManager::LayerCollision(Scene* scene, eColliderLayer leftLayer, eColliderLayer rightLayer)
	{
		const std::vector<Object*>& lefts = scene->GetObjects(leftLayer);
		const std::vector<Object*>& rights = scene->GetObjects(rightLayer);

		for (auto leftObject : lefts)
		{
			if (leftObject->GetCollider() == nullptr)
				continue;

			for (auto rightObject : rights)
			{
				if (rightObject->GetCollider() == nullptr)
					continue;
				if (rightObject == leftObject)
					continue;

				ColliderCollision(leftObject->GetCollider(), rightObject->GetCollider());
			}

			if (leftLayer == rightLayer)
				break;
		}
	}

๊ทธ ์™ธ ์กฐ๊ฑด๋“ค์„ ๋ชจ๋‘ ์ž˜ ์ฒ˜๋ฆฌํ–ˆ๋‹ค๋ฉด ์ถฉ๋Œ์ฒดํฌ๋ฅผ ์ง„ํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

InterSectํ•จ์ˆ˜๋กœ ์‹ค์ œ ์ถฉ๋Œ์ฒ˜๋ฆฌ๋ฅผ ํ•œํ›„์— ์ถฉ๋Œ ๋˜์—ˆ๋‹ค๋ฉด

์ตœ์ดˆ ์ถฉ๋Œ ๋˜์—ˆ์„๋–„๋Š” OnCollisionEnterํ•จ์ˆ˜

์ถฉ๋Œ์ค‘์ผ๋–„๋Š” OnCollisionStayํ•จ์ˆ˜

๊ทธ๋ฆฌ๊ณ  ์ถฉ๋Œ์ค‘์ธ ๋ฌผ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ๋น ์ ธ๋‚˜์™”์„๋•Œ๋Š” OnColllisionExitํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์ค€๋‹ค.

	void CollisionManager::ColliderCollision(Collider* left, Collider* right)
	{
		// ๋‘ ์ถฉ๋Œ์ฒด์˜  ID ํ™•์ธ
		ColliderID id;
		id.left = left->GetID();
		id.right = right->GetID();

		// ์ด์ „ ์ถฉ๋Œ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
		std::map<UINT64, bool>::iterator iter
			= mCollisionInfomations.find(id.ID);

		// ์ถฉ๋Œ์ •๋ณด๊ฐ€ ์—†๋‹ค๋ฉด ์ถฉ๋Œ์ •๋ณด๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.
		if (iter == mCollisionInfomations.end())
		{
			mCollisionInfomations.insert(std::make_pair(id.ID, false));
			iter = mCollisionInfomations.find(id.ID);
		}

		if (Intersect(left, right))
		{
			// ์ถฉ๋Œ ์ค‘
			if (iter->second == false)
			{
				//์ตœ์ดˆ ์ถฉ๋Œํ–ˆ์„๋•Œ
				left->OnCollisionEnter(right);
				right->OnCollisionEnter(left);
				iter->second = true;
			}
			else
			{
				//์ถฉ๋Œ ์ค‘์ผ๋•Œ
				left->OnCollisionStay(right);
				right->OnCollisionStay(left);
			}
		}
		else
		{
			// ์ถฉ๋Œ X
			if (iter->second)
			{
				left->OnCollisionExit(right);
				right->OnCollisionExit(left);
				iter->second = false;
			}

		}
	}

InterSectํ•จ์ˆ˜์—์„œ๋Š” ์ถฉ๋Œ์ฒด (๋„ค๋ชจ , ๋™๊ทธ๋ผ๋ฏธ ๋“ฑ๋“ฑ) ๋ฌผ์ฒด๋งˆ๋‹ค ์•Œ๋งž์€ ์ถฉ๋Œ์ฒดํฌ๋ฅผ ์ง„ํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๊ตฌํ˜„ํ•œ ๋„ค๋ชจ/๋„ค๋ชจ ์ถฉ๋Œ์— ๋Œ€ํ•ด์„œ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.

y ๊ฐ’์— ๋Œ€ํ•œ ํŒ๋‹จ

- A์˜ top์ด B์˜ bottom๋ณด๋‹ค ์ž‘๋‹ค.

- B์˜ top์ด A์˜ bottom๋ณด๋‹ค ์ž‘๋‹ค.

 

x ๊ฐ’์— ๋Œ€ํ•œ ํŒ๋‹จ

- A์˜ left๊ฐ€ B์˜ right๋ณด๋‹ค ์ž‘๋‹ค

- B์˜ left๊ฐ€ A์˜ right๋ณด๋‹ค ์ž‘๋‹ค.

 

์œ„ 4๊ฐœ์˜ ์กฐ๊ฑด์ด ๋ชจ๋‘ ๋™์‹œ์— ๋งŒ์กฑํ•ด์•ผ ๋‘ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๊ฒน์น˜๋Š” ๊ฒƒ ๋˜๋Š” ๋งŒ๋‚˜๋Š” ๊ฒƒ์ด ๋œ๋‹ค.

'๐Ÿ“ Development Study > ๐Ÿ’ป Win32API' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Alphablend, Camera Effect  (0) 2022.10.05
Camera  (1) 2022.10.04
Collider  (0) 2022.09.27
Component  (0) 2022.09.26
Path, Resource Load  (1) 2022.09.22

๋Œ“๊ธ€