Home 델타 타임(Delta time) 계산하기 - 게임에서 시간을 계산하는 방법
Post
Cancel

델타 타임(Delta time) 계산하기 - 게임에서 시간을 계산하는 방법

게임에서 시간 계산

게임에서 발생하는 물리 현상(캐릭터 이동부터 물체 파괴까지)은 시간에 영향을 받습니다. 그러면 어떻게 컴퓨터에서 시간을 정확하게 계산할 수 있을까요?

컴퓨터 성능에 의존하는 경우

일반적으로 이와 같은 상황에서 언급되는 함수는 Sleep입니다. Sleep은 밀리세컨드(milliseconds) 단위로 ‘지연’하는 함수입니다. 따라서 다음과 같이 코드를 작성할 수 있겠죠. (아래 코드에 따라 게임이 동작한다고 가정해봅시다.)

1
2
3
4
5
6
7
8
  while(false == bQuit)
  {
    Sleep(fTimeDelay);
    
    Game::Update();
    Game::Render();
    Game::Collide();
  }

문제점

그런데 이 Sleep 함수에는 문제가 있습니다. 우리가 원하는 정확한 시간을 주지 않는다는 것입니다. Sleep을 사용한 프로그램을 CPU 부하가 큰 상황과 그렇지 않은 상황에서 실행할 경우 시간 지연이 다르다는 것을 얻을 수 있습니다.

우리에게는 컴퓨터 성능에 의존하지 않는 시간이 필요합니다. 그러면 어떻게 컴퓨터에서 정확한 시간을 계산할 수 있을까요?

그러면 어떻게 시간을 계산하는가

Windows에서는 profileapi.h에 이전 프레임과 현재 프레임 사이의 시간을 정확하게 계산하기 위한 QueryPerformanceFrequencyQueryPerformanceCounter 가 있습니다.

1
BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpFrequency );

QueryPerformanceFrequency는 성능 카운터의 빈도를 돌려줍니다. 시스템 부팅시 고정되어 있으며 모든 프로세서에서 일관된 결과를 돌려줍니다.

1
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount );

QueryPerformanceCounter는 시간 간격 측정에 사용할 수 있는 고해상도 (<1us) 타임 스탬프인 성능 카운터의 현재 값을 돌려줍니다.

이제 컴퓨터에서 고정된 시간 값을 계산할 수 있겠군요.

DeltaTime Class

Delta time은 이전 프레임과 현재 프레임 사이의 시간을 말합니다. 그러면 우선 Time클래스를 작성해봅시다. 그리고 이를 통해 델타 타임을 얻어 봅시다.

이제 Timer클래스로 델타 타임만 가져올 수 있도록 작성해봅시다. 주석도 달아놨습니다만, Time클래스는 Timer의 이너 클래스(inner class)입니다.

어떻게 쓰면 되나요?

1
2
3
4
5
6
7
8
  while(false == bQuit)
  {
    Sleep(fTimeDelay);
    
    Game::Update();
    Game::Render();
    Game::Collide();
  }

이제 위 코드를 수정해봅시다.

1
2
3
4
5
6
7
8
9
10
11
  // 게임 프레임 시작 전 Reset하면 됩니다.
  Timer::Reset();
  
  while(false == bQuit)
  {
    Timer::Update();
    
    Game::Update();
    Game::Render();
    Game::Collide();
  }

그리고 이제는 다음과 같이 작성하면 정확한 시간에 따라 플레이어가 오른쪽으로 움직일 수 있게 구현할 수 있습니다.

1
2
// Game::Update()
  Player::MoveRight(speed * Timer::DeltaTime());

전체 코드는 여기서 확인하실 수 있습니다.

This post is licensed under CC BY 4.0 by the author.