League Of Legends - Link Select [winAPI 08] Object
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค“ Study/winAPI

[winAPI 08] Object

by GAMEMING 2024. 6. 5.
728x90

 

 

 ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ•œ Object ์ฝ”๋“œ์˜ updateํ•จ์ˆ˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ฝ”๋“œ์ด์ง€ ๋…ผ๋ฆฌ์ƒ ๋งž์ง€ ์•Š๋Š” ์ฝ”๋“œ์ด๋‹ค. ์ด Object ํด๋ž˜์Šค๋Š” ์•ž์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค ์—ฌ๋Ÿฌ ์˜ค๋ธŒ์ ํŠธ๋“ค์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด update๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฅผ ์ƒ์† ๋ฐ›์•„ ๋งŒ๋“ค์–ด์ง€๋Š” ์—ฌ๋Ÿฌ Object๋“ค์€ ํ˜„์žฌ ๊ตฌํ˜„๋œ ์ฝ”๋“œ์— ์˜ํ•ด WASD๋ฅผ ๋ˆ„๋ฅผ ๊ฒฝ์šฐ ์ด๋™ํ•˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰ ๋ชจ๋“  ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋˜‘๊ฐ™์€ ์ผ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. 

 

 ์˜ค๋ธŒ์ ํŠธ ํด๋ž˜์Šค๋ฅผ ์ƒ์† ๋ฐ›์•„ ์—ฌ๋Ÿฌ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๋ฐ ์”ฌ์˜ update ํ˜ธ์ถœ ์‹œ ๊ฐ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๊ฐœ์ธ์ ์œผ๋กœ ๊ฐ–๊ณ  ์žˆ๋Š” update๋ฅผ ์‹คํ–‰์‹œ์ผœ์ค˜์•ผ ๊ฐ์ž ํ•  ์ผ์„ ํ•˜์ง€ ์•Š์„๊นŒ? 

 

 ๋”ฐ๋ผ์„œ Object์— ์กด์žฌํ•˜๋Š” update์™€ renderํ•จ์ˆ˜๋Š” ๊ฐ€์ƒ ํ•จ์ˆ˜๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.

 

// Object.h

class Object {
private:
	Vec2	vPos;
	Vec2	vScale;

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

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

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

public:
	virtual void update();		// ์ˆ˜์ •
	virtual void render(HDC _hdc);	// ์ˆ˜์ •
};

 

 

์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ์›€์ง์ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด Player์„ ๋งŒ๋“ค์–ด๋ณด์ž.

 

// Player.h

#pragma once
#include "Object.h"

class Player : public Object {
public:
	virtual void update();
};



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

#include "KeyManager.h"
#include "TimeManager.h"

void Player::update()
{
	if (KeyManager::Instance()->GetKeyState(KEY::W) == KEY_STATE::HOLD) {
		vPos.y -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::S) == KEY_STATE::HOLD) {
		vPos.y += 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::A) == KEY_STATE::HOLD) {
		vPos.x -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::D) == KEY_STATE::HOLD) {
		vPos.x += 200.f * DT;
	}
}

 

 

update ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ๊ธฐ์กด Object์˜ update ํ•จ์ˆ˜์— ์žˆ๋˜ ๋ถ€๋ถ„์„ ๊ฐ€์ ธ์˜ค๊ณ  ๊ธฐ์กด ๋ถ€๋ถ„์„ ์‚ญ์ œํ•˜๋ฉด ๋œ๋‹ค. ๊ฐ€์ ธ์™”์„ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” Obejct ๋‚ด๋ถ€ ๋ณ€์ˆ˜ vPos๊ฐ€ private์ด๋ผ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

 

์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

void Player::update()
{
	Vec2 vPos = getPos();  

	if (KeyManager::Instance()->GetKeyState(KEY::W) == KEY_STATE::HOLD) {
		vPos.y -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::S) == KEY_STATE::HOLD) {
		vPos.y += 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::A) == KEY_STATE::HOLD) {
		vPos.x -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::D) == KEY_STATE::HOLD) {
		vPos.x += 200.f * DT;
	}

	setPos(vPos);
}

 

 

์ด์ œ ๊ธฐ์กด Start Scene์—์„œ Object๋กœ ๋งŒ๋“ค๋˜ ๊ฒƒ์„ ํ”Œ๋ ˆ์ด์–ด ๊ฐ์ฒด ์ƒ์„ฑ์œผ๋กœ ๋ฐ”๊ฟ”๋ณด์ž. ๊ธฐ์กด ๊ฒƒ๊ณผ ๊ตฌ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด Object ๊ฐ์ฒด๋„ ํ•˜๋‚˜ ์ผ๋‹จ ๋งŒ๋“ค์–ด๋ณด์ž.

 

// Scene_Start.cpp

void Scene_Start::Enter()
{
	// Object ์ถ”๊ฐ€
	Object* obj = new Player;

	obj->setPos(Vec2(640.f, 384.f));
	obj->setScale(Vec2(100.f, 100.f));

	AddObject(obj, GROUP_TYPE::DEFAULT);

	obj = new Object;  // ์–˜๋Š” ์•ˆ์›€์ง์ž„
	obj->setPos(Vec2(640.f, 384.f));
	obj->setScale(Vec2(100.f, 100.f));
	AddObject(obj, GROUP_TYPE::DEFAULT);
}

 

Player ๊ฐ์ฒด์™€ Object ๊ฐ์ฒด

 

 

 

์™ผ์ชฝ์€ W,S,A,D ํ‚ค ์ž…๋ ฅ์„ ํ†ตํ•ด ์›€์ง์ผ ์ˆ˜ ์žˆ๋Š” Player๊ฐ์ฒด๊ณ  ๊ฐ€์šด๋ฐ์— ์กด์žฌํ•˜๋Š” ๊ฐ์ฒด๋Š” ๊ธฐ์กด Object ๊ฐ์ฒด๋กœ update๋ถ€๋ถ„์ด ์—†์–ด ๊ฐ€๋งŒํžˆ ์žˆ๋‹ค.

 


 

 

๋ฐฉ๊ธˆ ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ ์ค‘์— ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค.

 

 

 

์—ฌ๊ธฐ์„œ Object ํด๋ž˜์Šค๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด๋„ ๋˜๋Š”๊ฑธ๊นŒ? Object ํด๋ž˜์Šค๋Š” ๊ฐ์ฒด ์ƒ์„ฑ์„ ์œ„ํ•œ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ, ์„ธ๋ถ€์ ์ธ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ƒ์†์˜ ๋ชฉ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ถ€๋ชจ ํด๋ž˜์Šค๋‹ค. ์ด ๋ถ€๋ชจ๊ฒฉ์˜ ํด๋ž˜์Šค๋ฅผ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†๊ฒŒ ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

 

๋ฐ”๋กœ ์ด ํด๋ž˜์Šค๋Š” ์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜ ํด๋ž˜์Šค๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ์กด

Object ํด๋ž˜์Šค ๋‚ด์˜ update ํ•จ์ˆ˜๋ฅผ ์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์ž.

 

 

// Object.h

// ์ˆ˜์ •
	virtual void update() = 0;

// Object.cpp

// ์•„๋ž˜ ์ฝ”๋“œ ์‚ญ์ œ
void Object::update()
{

}

 

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด ์ฝ”๋“œ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋œฌ๋‹ค.

 

 

 


 

 

์ขŒ์šฐ๋กœ ์ผ์ • ๊ฑฐ๋ฆฌ๋ฅผ ์›€์ง์ด๋Š” Monster๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž.

 

// Monster.h

#pragma once
#include "Object.h"

class Monster : public Object {
private:
	float		speed;
	float		maxDis;		// ์ตœ๋Œ€ ์ด๋™๊ฑฐ๋ฆฌ
	int		dir;		// ๋ฐฉํ–ฅ(1, -1)
	Vec2		centerPos;	// ์ค‘์•™ ๊ธฐ์ค€์ 

public:
	Monster();
	~Monster();

	virtual void update();

	float GetSpeed() { return speed; }
	void SetSpeed(float spd) { speed = spd; }
	
	void SetMoveDist(float dis) { maxDis = dis; }
	void SetCenterPos(Vec2 _pos) { centerPos = _pos; }
};


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

#include "TimeManager.h"

Monster::Monster()
	: speed(100.f)
	, centerPos(Vec2(0.f, 0.f))
	, maxDis(50.f)		
	, dir(1)
{
}

Monster::~Monster()
{
}

void Monster::update()
{
	Vec2 curPos = getPos();

	// ์ง„ํ–‰ ๋ฐฉํ–ฅ์œผ๋กœ ์‹œ๊ฐ„๋‹น speed๋งŒํผ ์ด๋™
	curPos.x += fDT * speed * dir;

	// ๋ฐฐํšŒ ๊ฑฐ๋ฆฌ ๊ธฐ์ค€์ ์„ ๋„˜์–ด์„ฐ๋Š”์ง€ ํ™•์ธ
	float dist = abs(centerPos.x - curPos.x) - maxDis ;

	if (0.f < dist) {
		// ๋ฐฉํ–ฅ ๋ณ€๊ฒฝ
		dir *= -1;
		curPos.x += dist * dir;
	}

	setPos(curPos);
}

 

// struct.h
// Add

	Vec2& operator = (POINT _pt)
	{
		x = (float)_pt.x;
		y = (float)_pt.y;
	}
    
   Vec2(const POINT& _pt)
		: x((float)_pt.x)
		, y((float)_pt.y)
	{
	}
    
// Core.h
// Add

	POINT GetResolution() { return ptResolution; }
    
    
// Scene_Start.cpp
// Add

	// Monster
	int monCount = 5;
	float moveDist = 25.f;
	float objScale = 50.f;
	Vec2 resolutions = Core::Instance()->GetResolution();
	float term = (resolutions.x - ((moveDist + objScale/2.f)* 2)) / (float)(monCount - 1);

	Monster* monsterObj = nullptr;
	for (int i = 0; i < monCount; ++i) {
		monsterObj = new Monster;
		monsterObj->SetCenterPos(Vec2((moveDist + objScale / 2.f) + (float)i * term, 50.f));
		monsterObj->setPos(Vec2(monsterObj->GetCenterPos()));
		monsterObj->SetMoveDist(moveDist);
		monsterObj->setScale(Vec2(objScale, objScale));
		AddObject(monsterObj, GROUP_TYPE::DEFAULT);
	}

 

ํ•ด์ƒ๋„๋ฅผ ๋ฐ˜์˜ํ•˜์—ฌ 5๊ฐœ์˜ ๋ชฌ์Šคํ„ฐ ์ƒ์„ฑ

 

 

 


 

 

๊ธฐ๋ณธ ๋ฏธ์‚ฌ์ผ ๊ตฌํ˜„

 

// Missile.h
#pragma once
#include "Object.h"

class Missile : public Object {
private:
	float		dir;  // ๋ฐฉํ–ฅ (์œ„/์•„๋ž˜)

public:
	Missile();
	~Missile();

	virtual void update();
	virtual void render(HDC _hdc);

	void SetDir(bool _up) 
	{ 
		if (_up)
			dir = -1.f;
		else
			dir = 1.f;
	}
};

 

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

#include "TimeManager.h"

Missile::Missile()
	: dir(1.f)
{
}

Missile::~Missile()
{
}

void Missile::update()
{
	Vec2 vPos = getPos();

	vPos.y += 600.f * fDT * (float)dir;

	setPos(vPos);
}

void Missile::render(HDC _hdc)
{
	Vec2 vPos = getPos();
	Vec2 vScale = getScale();

	Ellipse(_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));
}
// Player.h
#pragma once
#include "Object.h"

class Player : public Object {
private:
	void CreateMissile();

public:
	virtual void update();
};



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

#include "SceneManager.h"
#include "KeyManager.h"
#include "TimeManager.h"

#include "Scene.h"
#include "Missile.h"

void Player::update()
{
	Vec2 vPos = getPos();  

	if (KEY_HOLD(KEY::W)) {
		vPos.y -= 200.f * DT;
	}

	if (KEY_HOLD(KEY::S)) {
		vPos.y += 200.f * DT;
	}

	if (KEY_HOLD(KEY::A)) {
		vPos.x -= 200.f * DT;
	}

	if (KEY_HOLD(KEY::D)) {
		vPos.x += 200.f * DT;
	}

	if (KEY_TAP(KEY::SPACE)) {
		CreateMissile();
	}

	setPos(vPos);
}

void Player::CreateMissile()
{
	Vec2 missilePos = getPos();
	missilePos.y -= getScale().y / 2.f;

	Missile* missile = new Missile;
	missile->setPos(missilePos);
	missile->setScale(Vec2(25.f, 25.f));
	missile->SetDir(true);

	// ํ˜„์žฌ์”ฌ ์–ป์–ด์˜ด
	Scene* curScenes = SceneManager::Instance()->GetCurScene();
	curScenes->AddObject(missile, GROUP_TYPE::DEFAULT);
}
// define.h
#define KEY_CHECK(key, state) KeyManager::Instance()->GetKeyState(key) == state
#define KEY_HOLD(key) KEY_CHECK(key, KEY_STATE::HOLD)
#define KEY_AWAY(key) KEY_CHECK(key, KEY_STATE::AWAY) 
#define KEY_TAP(key) KEY_CHECK(key, KEY_STATE::TAP) 
#define KEY_NONE(key) KEY_CHECK(key, KEY_STATE::NONE)

 

 

 

 

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

[winAPI 10] Resource & Path Manager  (1) 2024.06.06
[winAPI 09] ๊ธฐ์ดˆ ์ˆ˜ํ•™  (0) 2024.06.05
[winAPI 07] Scene & Scene Manager  (1) 2024.06.04
[winAPI 06] Key Manager  (1) 2024.06.04
[winAPI 05] Double Buffering  (0) 2024.06.04