Timer의 필요성
Update문을 1 프레임마다 한번씩 수행됨
만약 input문을 이용하여 방향키의 입력마다 1씩 물체의 이동을 구현할 경우 Update문이 매 프레임마다 실행되어 fps만큼 이동하는 문제가 발생.
원하는 움직임 구현이 어려워지고 개인의 컴퓨터 성능에 따라 움직임이 다른 경우가 발생한다.
따라서 Timer을 사용하여 이전 프레임에서 현재 프레임까지 경과된 시간(deltaTime)을 곱해줌으로써 1초간 정해진 만큼의 움직임을 구현할 수 있음
#pragma once
class Timer
{
DECLARE_SINGLE(Timer);
public:
void Init();
void Update();
uint32 GetFps() { return _fps; } // Frame per second 최신 평균적인 Frame
float GetDeltaTime() { return _deltaTime; }
private:
uint64 _frequency = 0;
uint64 _prevCount = 0;
float _deltaTime = 0.f; // 이전 프레임에서 현재 프레임까지 경과된 시간
private:
// 프레임을 계산하기 위한 용도
uint32 _frameCount = 0; // Update문에 몇번 실행되었는지 계산.
float _frameTime = 0.f; // 누적시간
uint32 _fps = 0;
};
#include "pch.h"
#include "Timer.h"
// 어떤 시간을 기준으로 상대적인 시간의 흐름을 계산
void Timer::Init()
{
// GetTickCount64() // 정밀도가 떨어짐
::QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&_frequency));
::QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&_prevCount)); // CPU 클럭과 연관이 되어있다.
}
void Timer::Update()
{
// 현재 CPU 클럭 Count를 가져온다.
uint64 currentCount;
::QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(¤tCount));
// 현재 Count(CurrentCount)에서 전 Count(preCount)를 뺀 값을
// frequency로 나누어주면 경과된 시간이 나온다.
_deltaTime = (currentCount - _prevCount) / static_cast<float>(_frequency);
_prevCount = currentCount; // preCount에 currentCount를 저장
_frameCount++;
_frameTime += _deltaTime;
if (_frameTime > 1.f) // 1초를 넘어가는 순간
{
_fps = static_cast<uint32>(_frameCount / _frameTime); // 1초간 Update문이 몇번 실행되었는지
_frameTime = 0.f; // 0으로 초기화
_frameCount = 0; // 0으로 초기화
}
}
_deltaTime = (currentCount - _prevCount) / static_cast<float>(_frequency);
// 아래 코드는 1초에 1씩 움직이는 코드이다.
output.x+=1*deltaTime;