개발하는 리프터 꽃게맨입니다.

[WinAPI] DeltaTime 본문

Window API

[WinAPI] DeltaTime

파워꽃게맨 2024. 2. 1. 19:55

 

이런 오브젝트가 있다고 해봅시다.

이 오브젝트는 방향키를 누르면 상하좌우로 움직이며

그 값은 0.1 만큼 움직입니다.

 

그런데 이 코드에는 문제가 있죠.

 

바로 하드웨어 성능에 따라 초당 이동거리가 다르다는 것입니다.

 

이게 무슨 의미일까요?

 

컴퓨터 A는 계산속도가 매우 빨라서 1초에 10000번 계산합니다.

컴퓨터 B는 계산속도가 매우 느려서 1초에 100번 계산합니다.

 

위 코드에 의하면

컴퓨터 A에서 게임을 실행시 1초에 1000 만큼 이동하고

컴퓨터 B에서는 게임을 실행시 1초에 10 만 이동하죠.

 

만약, 레이싱 게임이라고 했을때

내 컴퓨터 사양이 구리다는 이유로 매번 경기에서 지면 억울할겁니다.

 

그렇기에 컴퓨터 사양에 구애받지 않는 상대적인 시간을 얻어야하는데 그것이 바로 

델타타임 입니다.

 

그럼 이는 어떻게 계산할까요?

 

델타타임은 프로그램 루프가 한 바퀴도는데 걸리는 시간입니다.

while(true) 루프가 있을때

루프 한 번 돌때의 시간을 뜻하죠.

 

그러면 이런 식으로 구할 수 있습니다.

 

 

QueryPerformanceCounter를 통해 시간을 측정할 수 있고

 

현재 시간 - 이전 시간 값을 구하면

루프를 1번 돌 때, 소모한 시간의 길이를 구할 수 있습니다.

 

이제 시간 값을 구하기 위해서는

길이에다가 속도를 나눠야 하죠.

이 때 우리는 frequency

주파수를 구해서 나눠주면 deltaTime을 구할 수 있습니다.

 

 

이렇게 말이죠.

 

 

이것이 델타 타임을 출력했을때 얻어내는 값입니다. 

 

이제 처음 문제로 돌아가서

델타타임이 어떻게 모든 컴퓨터에서 1초에 동일한 거리를 움직일 수 있게 해줄까요?

 

예를들어

 

 

이런 식으로 바꿔보겠습니다.

delta는 델타타임입니다.

 

delta 는 한 루프를 도는데 걸리는 시간입니다.

컴퓨터 A에서 한 루프를 도는데 0.001 초

컴퓨터 B에서 한 루프를 도는데 0.1 초 걸렸다고 해봅시다.

 

컴퓨터 A는 한 루프당 0.5 만큼 이동할 것이고

컴퓨터 B는 한 루프당 50 만큼 이동할 것입니다.

 

총 1초 동안 루프를 돈다고 했을 때,

컴퓨터 A는 루프를 1000번, B는 루프를 10번 돌았습니다.

 

그리고 결과적으로

컴퓨터 A는 0.5 * 1000 = 500 만큼 움직였고

컴퓨터 B는 50 * 10 = 500 만큼 움직였습니다.

 

동일하게 움직였죠? 이것이 델타 타임을 사용하는 이유입니다.

 

자, 그러면 내김에 fps도 구해보도록 하죠.

 

fps는 frame per second 

초당 몇 번의 프레임이 그려졌냐는 뜻인데,

여기서는 초당 몇 번의 루프가 돌아갔냐라는 뜻으로 받아들이면 되겠습니다.

 

 

코드는 위와 같습니다.

 

frameCnt는 루프가 한 번 돌아갈 때마다 누적됩니다.

 

루프들이 돌아가는 시간을 누적해서

1초가 될 때까지 누적한 뒤

 

루프가 돌아간 횟수 / 1초를 나눠줘서

fps를 구합니다.

 

이제 이걸 싱글톤으로 바꿔서 TimeManager 클래스로 만들어보겠습니다.

 

 

이런 식으로 매니저 클래스를 만들어서

 

 

이런 식으로 가공해주면 됩니다.

 

 

글자를 통해서 fps와 delta time을 출력해봤습니다.

 

 

이제 이런 식으로 deltatime만 뽑아서

플레이어한테 곱해주면

 

플레이어는 어떤 PC에서 동작하던지 상관없이 초당 500픽셀을 이동하게 됩니다.