League Of Legends - Link Select [winAPI 12] Collider(1)
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค“ Study/winAPI

[winAPI 12] Collider(1)

by GAMEMING 2024. 6. 6.
728x90

 

์ถฉ๋Œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด๋ณด์žฅ..

๊ฒŒ์ž„์—์„œ ์ถฉ๋Œ์€ ๋งค์šฐ ํ•„์ˆ˜์ ์ธ ๋ถ€๋ถ„์ด๋‹ค. ์ถฉ๋Œ์€ ๋‹จ์ˆœํžˆ ๋ถ€๋”ช์ณค๋‹ค๋Š” ํ•˜๋‚˜์˜ ์‚ฌ์‹ค์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ์กฐ๊ฑด์ด ํ•„์š”ํ•˜๋‹ค. ์•„๋ž˜์—์„œ ์ด ์กฐ๊ฑด์— ๋”ฐ๋ผ ์„ธ ๊ฐ€์ง€ ์ด๋ฒคํŠธ๋กœ ๋‚˜๋ˆŒ ๊ฒƒ์ด๋‹ค. 

 

์˜ค๋ธŒ์ ํŠธ์— ์ถฉ๋Œ์ด ํ•„์š”ํ•œ ๊ฒƒ์ด ์žˆ๊ณ , ์•„๋‹Œ ๊ฒฝ์šฐ(๋ฐฐ๊ฒฝ, UI ๋“ฑ)๊ฐ€ ์žˆ๋‹ค. ์˜ค๋ธŒ์ ํŠธ ๋‚ด์—์„œ Collider ์™€ Non-Collider๋กœ ๋‚˜๋ˆ„์–ด ์ƒ์†์„ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•˜๋ฉด ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค. Non-Collider ์ค‘์—์„œ ์ผ๋ถ€๋งŒ ์ถฉ๋Œ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๋ฉด ๊ตฌ์กฐ๋ฅผ ๋‹ค ๋œฏ์–ด ๊ณ ์ณ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ. ๊ทธ๋ž˜์„œ ์ƒ์† ๊ตฌ์กฐ์˜ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ๊นŠ๋‹ค๋ฉด(์ƒ์†-์ƒ์†-์ƒ์†...) ์ด๋Ÿฐ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ํ™•๋ฅ ์ด ๋†’๋‹ค.

 

์ด๋Ÿฐ ๋ฉค๋ฒ„๋Š” ํ•ญ์ƒ ๊ฐ–๊ณ  ์žˆ๋˜ ํ•„์š”ํ•˜๋ฉด ์“ฐ๊ณ , ์•„๋‹ˆ๋ฉด ์•ˆ ์“ฐ๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. ์ด๋Ÿฐ ์• ๋“ค์„ component๋ผ๊ณ  ๋ถ„๋ฅ˜ํ•˜๊ณ  ์–˜๋„ค๋Š” ๋”ฐ๋กœ class๋ฅผ ๋งŒ๋“ค์–ด ๊ตฌํ˜„ํ•œ๋‹ค.

 

ํ˜„์žฌ ๊ตฌํ˜„๋œ ํ•„ํ„ฐ & ํŒŒ์ผ

 

 

Collider๋Š” Object ์•ˆ์—์„œ ๋ถ€ํ’ˆ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•จ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋”ฉ๋œ๋‹ค.

class Object {
private:
	Vec2		vPos;
	Vec2		vScale;
	Collider*	collider;	// ํ•„์š”ํ•˜๋ฉด ์‚ฌ์šฉ, ํ•„์š” ์—†์œผ๋ฉด nullptr

public:
	Object();
	virtual ~Object();

	void setPos(Vec2 _vPos) { vPos = _vPos; }
	void setScale(Vec2 _vScale) { vScale = _vScale; }

	Vec2 getPos() { return vPos; }
	Vec2 getScale() { return vScale; }

	Collider* GetCollider() { return collider; }	// New!!
	void CreateCollider();				// New!!

public:
	virtual void update() = 0;
	virtual void render(HDC _hdc);
	virtual void finalUpdate() final;	// ์ž์‹์—์„œ์˜ ์˜ค๋ฐ”๋ผ์ด๋”ฉ ๊ธˆ์ง€๋จ.

	void commponentRender(HDC _hdc);	// New!! (์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฆผ)
};

 

 

์šฐ์„  ์ถฉ๋Œ์ด ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ธฐ์— CreateCollider ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ํ•œ๋‹ค.

void Object::CreateCollider()
{
	collider = new Collider;
	collider->owner = this;	
}

 

 

์–ด๋–ค ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ถฉ๋Œ์„ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•จ์œผ๋กœ Collider ๋‚ด๋ถ€์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋”ฉ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

// Collider.h

class Object;	// ์–˜๊ฐ€ ๋ˆ„๊ตฌ ์†Œ์†์ธ์ง€๋ฅผ ์•Œ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์˜ค๋ธŒ์ ํŠธ ํ•„์š”

class Collider	{
private:
	Object* owner;

public:
	Collider();
	~Collider();

	friend class Object;
};


// Collider.cpp
#include "pch.h"
#include "Collider.h"

#include "Object.h"

Collider::Collider()
	: owner(nullptr)
{
}

Collider::~Collider()
{
}

 

 

์ถฉ๋Œ์ด ์กด์žฌํ•˜๋Š” Player, Monster, Missile ๊ฐ์ฒด ๋“ฑ ์ถฉ๋Œ์ด ํ•„์š”ํ•œ ๊ฐ์ฒด์— ๊ฐ๊ฐ CreateColliderํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ๋„๋ก ํ•œ๋‹ค.

 

 

 


 

 

์ƒ๊ฐํ•ด๋ณด์ž. ์ถฉ๋Œ์€ ๊ฒŒ์ž„ ๋กœ์ง์ƒ update๊ฐ€ ์•„๋‹ˆ๋ผ ์ถฉ๋Œ์ฒ˜๋ฆฌ๋Š” ๊ณ„์† ๋ฐœ์ƒํ• (update) ์ƒํ™ฉ์ž„. ์šฐ๋ฆฌ๊ฐ€ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ์•Œ์•„์„œ ๊ณ„์† ์ง„ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์• ๋“ค์ž„์œผ๋กœ ์–˜๋„ค๋ฅผ ๋”ฐ๋กœ ๋ชจ์•„ ์ˆ˜ํ–‰์‹œ์ผœ์ฃผ์ž

 

์ฆ‰ ์ตœ์ข… ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์ž. ์ด๋Š” ํ˜„์žฌ ์”ฌ์—์„œ ์—…๋ฐ์ดํŠธ ์‹œ์ผœ์ฃผ์–ด์•ผ ํ•จ์œผ๋กœ Scene Manager์™€ Scene์—  finalUpdate()ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

 

์”ฌ์—์„œ ๋ชจ๋“   Object ๋Œ€ํ•ด์„œ finalUpdateํ•จ์ˆ˜๊ฐ€ ๋ถˆ๋ฆฌ์›€์œผ๋กœ ์ด๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š”๋ฐ Object์— ์ถฉ๋Œ์ด ๋ถ™์–ด ์žˆ๋Š” ๊ฒƒ์ž„์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ(์ž์‹ํด๋ž˜์Šค์˜ ์žฌ์ •์˜)์„ ๊ธˆ์ง€ ์‹œ์ผœ์•ผ ํ•จ์œผ๋กœ final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

Object.h
Object.cpp

 

Object์˜ finalUpdateํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” Collider์˜ ํ•จ์ˆ˜๊ฐ€ ๋ถˆ๋ ค์•ผ ํ•จ์œผ๋กœ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋†”์•ผ ํ•œ๋‹ค.

 

// SceneManager.cpp
void SceneManager::update()
{
	currScene->update();
	currScene->finalUpdate();	// ์ถ”๊ฐ€
}


// Scene.cpp
void Scene::finalUpdate()	// ์ถ”๊ฐ€
{
	for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i) {
		for (size_t j = 0; j < arrObj[i].size(); ++j) {
			arrObj[i][j]->finalUpdate();
		}
	}
}


// Collider.h ์ถ”๊ฐ€
	void finalUpdate();
    
    
// Collider.cpp
void Collider::finalUpdate()
{
	Vec2 objectPos = owner->getPos();
	finalPos = objectPos + offsetPos;
}


// Struct.h
	Vec2 operator +(Vec2 other)
	{
		return Vec2(x + other.x, y + other.y);
	}

	Vec2 operator -(Vec2 other)
	{
		return Vec2(x - other.x, y - other.y);
	}

	Vec2 operator *(Vec2 other)
	{
		return Vec2(x * other.x, y * other.y);
	}

	Vec2 operator /(Vec2 other)
	{
		assert(!(0.f == other.x || 0.f == other.y));
		return Vec2(x / other.x, y / other.y);
	}

 

 


 

 

์ถฉ๋Œ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ ๋ณดํ†ต ๊ทธ ์˜์—ญ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ”์šด๋”ฉ ๋ฐ•์Šค๋ฅผ ๊ทธ๋ฆฐ๋‹ค. ์ด๋ฅผ ๊ณ ๋ คํ•ด ์™„์„ฑ๋œ ์ฝ”๋“œ์ด๋‹ค.

 

// define.h

// ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ธŒ๋Ÿฌ์‰ฌ์™€ ํŽœ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘์ž.

enum class BRUSH_TYPE {
	HOLLOW,
	END,
};

enum class PEN_TYPE {
	RED,
	GREEN,
	BLUE,
	END,
};


// Core.h
class Core {
	SINGLE(Core);
private:
	HWND    handle;
	POINT   ptResolution;
	HDC		hDC;

	HBITMAP hBit;
	HDC     mDC;

	// ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” GDI Object
	HBRUSH	arrBrush[(UINT)BRUSH_TYPE::END];
	HPEN	arrPen[(UINT)PEN_TYPE::END];

public:
	int Init(HWND _hWnd, POINT _ptResolution);
	void Progress();

	void CreateBrushPen();		// ์ถ”๊ฐ€

	HWND getMainHandle() { return handle; }
	HDC GetMainDC() { return hDC; }
	POINT GetResolution() { return ptResolution; }
	HBRUSH	GetBrush(BRUSH_TYPE _type) { return arrBrush[(UINT)_type]; }	// ์ถ”๊ฐ€
	HPEN	GetPen(PEN_TYPE _type) { return arrPen[(UINT)_type]; }		// ์ถ”๊ฐ€
};


// Core.cpp
Core::Core()
	:handle(0)
	, ptResolution{}
	, hDC(0)
	, hBit(0)
	, mDC(0)
	, arrBrush{}
	, arrPen{}
{

}

int Core::Init(HWND _handle, POINT _ptResolution)
{
	// ..
    // ์ž์ฃผ ์‚ฌ์šฉ ํ•  ํŽœ ๋ฐ ๋ธŒ๋Ÿฌ์‰ฌ ์ƒ์„ฑ
	CreateBrushPen();
	// ..
}

void Core::CreateBrushPen()
{
	// Hollow Brush
	arrBrush[(UINT)BRUSH_TYPE::HOLLOW] = (HBRUSH)GetStockObject(HOLLOW_BRUSH);

	// Red / Blue / Green Pen
	arrPen[(UINT)PEN_TYPE::RED] = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	arrPen[(UINT)PEN_TYPE::BLUE] = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
	arrPen[(UINT)PEN_TYPE::GREEN] = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
}
class Collider	{
private:
	Object* owner;		// collider๊ฐ€ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋Š” obj

	Vec2	offsetPos;
	Vec2	finalPos;	// finalUpdate์—์„œ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๊ณ„์‚ฐ

	Vec2	scale;		// ์ถฉ๋Œ์ฒด ํฌ๊ธฐ

public:
	Collider();
	~Collider();

	void SetOffsetPos(Vec2 _pos) { offsetPos = _pos; }
	void SetScale(Vec2 _scale) { scale = _scale; }

	Vec2 GetOffsetPos() { return offsetPos; }
	Vec2 GetScale() { return scale; }

	void finalUpdate();
	void render(HDC _hdc);

	friend class Object;
};


// Collider.cpp
#include "pch.h"
#include "Collider.h"

#include "Object.h"
#include "Core.h"
#include "SelectGDI.h"

Collider::Collider()
	: owner(nullptr)
{
}

Collider::~Collider()
{
}

void Collider::finalUpdate()
{
	Vec2 objectPos = owner->getPos();
	finalPos = objectPos + offsetPos;
}

void Collider::render(HDC _hdc)	// 	๋ฐ”์šด๋”ฉ ๋ฐ•์Šค
{
	SelectGDI p(_hdc, PEN_TYPE::RED);	
	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));
}

 

 

์ถฉ๋Œ์€ ํ—ค๋“œ/๋ชธํ†ต/๋‹ค๋ฆฌ ์ด๋ ‡๊ฒŒ ๋”ฐ๋กœ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ ์˜๋ฏธํ•˜๋Š” offset์€ ์–ด๋–ค ๊ธฐ์ค€ ์œ„์น˜๋กœ๋ถ€ํ„ฐ ์–ผ๋งŒํผ ๋–จ์–ด์กŒ๋Š” ๊ฐ€๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๊ทธ ๊ธฐ์ค€์€ ๊ธฐ์ค€ : Object Pos๋กœ ๋งŒ์•ฝ offset์ด ์ œ๋กœ๋ผ๋ฉด ์˜ต์  ์ขŒํ‘œ์™€ ๋™์ผํ•˜๋‹ค.

 

// Object.h

#pragma once

class Collider;

class Object {
private:
	Vec2		vPos;
	Vec2		vScale;
	Collider*	collider;

public:
	Object();
	virtual ~Object();

	void setPos(Vec2 _vPos) { vPos = _vPos; }
	void setScale(Vec2 _vScale) { vScale = _vScale; }

	Vec2 getPos() { return vPos; }
	Vec2 getScale() { return vScale; }

	Collider* GetCollider() { return collider; }
	void CreateCollider();

public:
	virtual void update() = 0;
	virtual void render(HDC _hdc);
	virtual void finalUpdate() final;

	void commponentRender(HDC _hdc);	// ๊ทธ๋ฆฌ๊ธฐ
};



// Object.cpp

#include "pch.h"
#include "Object.h"

#include "pch.h"

#include "Collider.h"

Object::Object()
	: vPos{}
	, vScale{}
	, collider(nullptr)
{
}

Object::~Object()
{
	if (nullptr != collider)
		delete collider;
}

void Object::render(HDC _hdc)
{
	Rectangle(_hdc, (int)(vPos.x - vScale.x / 2.f), (int)(vPos.y - vScale.y / 2.f),
		(int)(vPos.x + vScale.x / 2.f), (int)(vPos.y + vScale.y / 2.f));

	commponentRender(_hdc);
}

void Object::finalUpdate()
{
	if (collider)
		collider->finalUpdate();
}

void Object::commponentRender(HDC _hdc)
{
	if (nullptr != collider)
		collider->render(_hdc);	// ์ถฉ๋Œ ํด๋ž˜์Šค์˜ ๋ Œ๋” ํ•จ์ˆ˜ ํ˜ธ์ถœ
}

void Object::CreateCollider()
{
	collider = new Collider;
	collider->owner = this;	 
}

 

 

 

 

๋ณธ๋ž˜ ์•„๋ž˜์˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ๊ฐ ํŽœ๊ณผ ๋ธŒ๋Ÿฌ์‰ฌ๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•œ ํ›„ ๊ธฐ์กด ๊ป„๋กœ ๋‹ค์‹œ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ท€์ฐฎ์€ ์ž‘์—…์ด ํ•„์š”ํ•œ๋ฐ ์ด๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด selectGDI ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ํ•œ๋‹ค.

 

๋„ˆ๋ฌด ๊ธธ๋‹น.

 

 

// SelectGDI.h
#pragma once
class SelectGDI {
private:
	HDC		hDC;
	HPEN	defaultPen;
	HBRUSH	defaultBrush;
public:
	SelectGDI(HDC _dc, PEN_TYPE _type);
	SelectGDI(HDC _dc, BRUSH_TYPE _type);
	~SelectGDI();
};

// SelectGDI.cpp
#include "pch.h"
#include "SelectGDI.h"

#include "Core.h"

SelectGDI::SelectGDI(HDC _dc, PEN_TYPE _type)
	: hDC(_dc)
	, defaultBrush(nullptr)
	, defaultPen(nullptr)
{
	HPEN greenPen = Core::Instance()->GetPen(_type);
	defaultPen = (HPEN)SelectObject(_dc, greenPen);
}

SelectGDI::SelectGDI(HDC _dc, BRUSH_TYPE _type)
	: hDC(_dc)
	, defaultBrush(nullptr)
	, defaultPen(nullptr)
{
	HBRUSH hollowBrush = Core::Instance()->GetBrush(_type);
	defaultBrush = (HBRUSH)SelectObject(_dc, hollowBrush);
}

SelectGDI::~SelectGDI()
{
	SelectObject(hDC, defaultPen);
	SelectObject(hDC, defaultBrush);
}
// Collider.cpp

void Collider::render(HDC _hdc)	// ์ฒดํฌ๋ฐ•์Šค
{
	// ํ…Œ๋‘๋ฆฌ ๋ผ์ธ๋งŒ ๊ทธ๋ฆฌ๋„๋ก -> ์ž์ฃผ ์‚ฌ์šฉํ•  ํŽœ์€ ์ฝ”์–ด์—์„œ ๊ด€๋ฆฌ
	SelectGDI p(_hdc, PEN_TYPE::RED);	
	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));
}

 

 

 

 

์ถ”๊ฐ€๋œ ์ฝ”๋“œ๊ฐ€ ๊ฝค ๋งŽ์œผ๋‹ˆ ์•„๋ž˜์˜ ๋งํฌ์—์„œ ์ •ํ™•ํ•œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•˜์ž.

https://github.com/MiyeongEom/GameBasic/commit/50c36b47990e83c1a28bf6a86c9427b7c4f82492

 

~ Collider(1) · MiyeongEom/GameBasic@50c36b4

MiyeongEom committed Jun 6, 2024

github.com

 

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

[winAPI 14] Collider(3)  (1) 2024.06.09
[winAPI 13] Collider(2)  (1) 2024.06.08
[winAPI 11] Resource Manager  (0) 2024.06.06
[winAPI 10] Resource & Path Manager  (1) 2024.06.06
[winAPI 09] ๊ธฐ์ดˆ ์ˆ˜ํ•™  (0) 2024.06.05