์ง๊ธ๊น์ง ์์ฑํ 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);
}
์ผ์ชฝ์ 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);
}
๊ธฐ๋ณธ ๋ฏธ์ฌ์ผ ๊ตฌํ
// 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 |