WIN32 Timer
카테고리: WINAPI
5일차
- Default
- Client.h
- framework.h
- Resouce.h
- targetver.h
- Engine
- Header
- define.h
- struct.h
- Core
- CCore.cpp
- CCore.h
- Manager
- KeyMgr
- CkeyMgr.cpp
- CkeyMgr.h
- TimeMgr
- CTimeMgr.cpp
- CTimeMgr.h
- KeyMgr
- Object
- CObject.cpp
- CObject.h
- Header
- 리소스 파일
- main.cpp
- pch.h.
- struct.h
#pragma once
struct Vec2 {
float x;
float y;
public:
Vec2()
: x(0.f)
, y(0.f)
{}
Vec2(float _x, float _y)
: x(_x)
, y(_y)
{}
Vec2(int _x, int _y)
: x((float)_x)
, y((float)_y)
{}
};
화면에 표시될 좌표 처리를 float으로 해야하므로, Vec2라는 float형 구조체를 만들어주었다. 또한 생성자까지 덤으로.
- CCore.h
#pragma once
class CObject
{
private:
Vec2 m_vPos;
Vec2 m_vScale;
public:
void SetPos(Vec2 _vPos) { m_vPos = _vPos; }
void SetScale(Vec2 _vScale) { m_vScale = _vScale; }
Vec2 GetPos() { return m_vPos; }
Vec2 GetScale() { return m_vScale; }
public:
CObject();
~CObject();
};
오브젝트의 좌표를 float형으로 모두 바꿨다. 은닉하면서 Set, Get까지 전부 다.
- CCore.cpp
#include "pch.h"
#include "CObject.h"
CObject::CObject()
: m_vPos{}
, m_vScale{}{
}
CObject::~CObject() {
}
이니셜라이저 바꿔주고.
- CCore.cpp
#include "pch.h"
#include "CCore.h"
#include "CTimeMgr.h"
#include "CkeyMgr.h"
#include "CObject.h"
//CCore* CCore::g_pInst = nullptr;
CObject g_obj;
CCore::CCore()
: m_hWnd(0), m_ptResolution{}, m_hDC(0)
{
}
CCore::~CCore() {
//m_hWnd에 엮여있던 m_hDC를 해제해준다.
ReleaseDC(m_hWnd, m_hDC);
}
int CCore::init(HWND _hWnd, POINT _ptResolution) {
m_hWnd = _hWnd;
m_ptResolution = _ptResolution;
//해상도에 맞게 윈도우 크기 조정.
RECT rt = { 0,0,m_ptResolution.x, m_ptResolution.y };
//테두리 포함해서, 크기 보정해주는 것.
//rt 포인터에다가 다시 값을 변환해서 넣어줌.
AdjustWindowRect(&rt, WS_OVERLAPPEDWINDOW, true);
//타이틀이나 그런 걸 제외한, 순수하게 물체가 그려질 수 있는 영역.
//첫 번째로 들어가는 건, 어떤 윈도우인지.
//SetWindow는 타이틀창이나 테두리까지 포함한 크기임.
SetWindowPos(m_hWnd, nullptr, 100, 100, rt.right - rt.left, rt.bottom - rt.top, 0);
//어디다가 그려요? m_hWnd에다가 그려요.
m_hDC = GetDC(m_hWnd);
//Manager initialize
CTimeMgr::GetInstance()->init();
CkeyMgr::GetInstance()->init();
g_obj.SetPos(Vec2((float)(m_ptResolution.x / 2), (float)(m_ptResolution.y / 2)));
g_obj.SetScale(Vec2(100, 100));
return S_OK;
}
void CCore::progress() {
update();
render();
}
void CCore::update()
{
Vec2 vPos = g_obj.GetPos();
//비동기 키 입출력 함수. <- 코드가 바로 실행됨. 백그라운드여도 바로 수행됨
//return 되는 건 어느정도 상태 값을 알려줌.
if (GetAsyncKeyState(VK_LEFT) & 0x8000) {
//왼쪽 키가 눌렸을 경우.
//정수대로 움직이면, 엄청난 이동속도가 됨.
//107.7이 좌표더라고 107이나 108이 됨.
//컴퓨터 성능에 따라 움직이는 양이 달라질 것.
//그래서 시간 동기화가 필요함. 1초마다 움직이는 양이 정해져야만 함.
vPos.x -= 0.01f;
}
if (GetAsyncKeyState(VK_RIGHT) & 0x8000) {
vPos.x += 0.01f;
}
//물체들의 변경점을 체크하는 곳(좌표나 여러가지 변경점)
g_obj.SetPos(vPos);
}
void CCore::render()
{
//그리기 작업.
Vec2 vPos = g_obj.GetPos();
Vec2 vScale = g_obj.GetScale();
Rectangle(m_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));
//검은 잔상이 남는데, 움직일 때마다 전부 안지워줘서 그럼.
}
0.01f단위로 움직이게 바꾸어주었다. 또한 update()에서 키 입력을 비동기적으로 받도록 만들어주었다.
- 프레임이 몇 천~ 몇 만이 나오는데 + 0.01되면 1초당 균일한 속도가 안나와서 시간 동기적인 프로그램을 만들어야함.
- CTimeMgr.h
#pragma once
class CTimeMgr
{
SINGLE(CTimeMgr);
private:
//이동량을 프레임으로 쪼개서 이동을 시키면, 이번 프레임에 움직이는 양이 나옴.
//이동량 * 1프레임에 걸리는 시간(delta Time).
LARGE_INTEGER m_llCurCount;
LARGE_INTEGER m_llFrequency;
public:
//GetTick은 1초당 1000이라서 정확도가 조금...
//게다가 오차도 있어서 훨씬 더 정밀한 함수가
//QueryPerformanceCounter(); -> 1000만 단위.
void init();
};
- CTimeMgr.cpp
#include "pch.h"
#include "CTimeMgr.h"
CTimeMgr::CTimeMgr()
:m_llCurCount{}
,m_llFrequency{}
{
}
CTimeMgr::~CTimeMgr() {
}
void CTimeMgr::init()
{
QueryPerformanceCounter(&m_llCurCount);
//초당 카운트가 고정되어 있는것도 아님.
QueryPerformanceFrequency(&m_llFrequency);
}
댓글 남기기