WIN32API FrameWork/한단계씩 직접 구현

07. DeltaTime

2022. 5. 16. 16:00

https://hyrule.tistory.com/111 

 

*** 공부 방법 ***

1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. (ex)

hyrule.tistory.com


[프레임과 게임 처리]
내 컴퓨터는 100프레임
PC방 컴퓨터는 200프레임

게임 코드는 1프레임당 한번 게임 로직을 처리
만약 게임 로직이 1프레임에 5씩 캐릭터를 이동시킨다면
내 컴퓨터에서 500 움직일 동안 PC방 컴퓨터는 1000을 움직이게 된다.
아주 심각한 문제

<해결법 - DeltaTime>
* 매 프레임마다 한 프레임을 그리는 데 걸렸던 시간을 변수에 저장한다.
* 그리고 다음 프레임을 그릴때 시간 단위를 위에서 저장한 변수로 처리한다.
* 그러면 프레임 수에 게임 속도가 빨라지거나 느려지는 문제가 발생하지 않는다.
* 그러므로 앞으로 모든 게임 로직 처리 함수에 인자로 DeltaTime을 넣어줘서 처리한다.

 

* 윈도우는 고해상도 타이머를 내장하고 있고, api에서 이 고해상도 타이머의 초당 진동수와 값을 얻어올 수 있다.
* 프레임과 프레임 사이의 시간을 구하고자 한다면 고해상도 타이머의 값을 얻어와서 구할 수 있다.

 

 


<사전 지식>

 

* LARGE_INTEGER, 공용체

https://hyrule.tistory.com/86

 

LARGE_INTEGER , 공용체(Union)

    * LARGE_INTEGER: 공용체(union)     - 공용체는 메모리 공간을 공유하는 메모리 타입이다.     * 32비트 기준         - DWORD LowPart = Unsigned int (4byte)    ..

hyrule.tistory.com

 

QueryPerformanceFrequency(&LARGE_INTEGER)

 

 - 들어온 LARGE_INTEGER 타입 변수의 '주소'에 현재 타이머의 1초당 진동수를 저장한다.

 

QueryPerformanceCounter(&LARGE_INTEGER)

 - 들어온 LARGE_INTEGER 타입 변수의 '주소'에 현재 타이머의 시간을 기록한다.

 

 

char TimeText[64] = {};
sprintf_s(TimeText, "Deltatime: %.5f", DeltaTime);

 

2번 인자의 문자열 + 

3번 인자의 데이터를 문자열로 바꾸어 합한 뒤

1번 인자에 삽입한다.

DeltaTime = 1.0f라고 가정하면

TimeText를 출력 시

"Deltatime: 1.00000"이 출력된다.

 


//신규 클래스
class CTimer

DeltaTime, 프레임 제한, 평균 프레임 연산 등의 작업을 수행할 클래스

GameManager의 하위 필터로 Timer를 만들어 모아 놓자.

 

< 구현해야 할 것들 >

 

* 타이머 계산 방법

  1. 타이머의 초당 진동수를 받아놓음(ex.초당 1000.f번 진동)
  2. 이전 게임로직 한 사이클 시작 시간 기록(ex.100.f)
  3. 게임 한 사이클 종료 시간 기록(ex.200.f)
  4. (종료 시간 - 시작 시간) / 초당 진동수 = 한 프레임 그리는데 걸리는 시간(초 단위)
    1. 주의)타이머가 기록한 시간의 종류는 모두 LONG LONG 타입이고,
      우리가 구하는 DeltaTIme은 float 타입이다. 형변환 해줘야 함.
  5. (200 - 100) / 1000 = 0.1
  6. 한 프레임을 그리는데 0.1초가 지났으므로 다음 프레임을 그릴 때는 0.1초 지난 상태를 그려주면 된다.

 

CTimer::Init()

초기화 메소드. 값을 초기화 하고 초당 진동수를 등록해 준다.

 

 

CTimer::Update()

매 게임로직에서 실행될 메소드.

void 형식으로 CTimer 내부에서 선언한 변수에 따로 저장하거나,

float 형식으로 DeltaTime 값을 반환받아도 된다.

DeltaTime값은 GameManager에서 관리한다.

  • DeltaTime을 계산
  • 초당 프레임 수를 계산
  • 초당 프레임 수 제한

 

 

CTimer::SetFrameLimit()

int값을 인자로 받아서, 초당 프레임을 인자만큼으로 제한한다.

0을 입력하면, 프레임 제한을 해제한다.

 


//코드 수정
class CGameManager

CTimer 구현이 끝났으면,

CGameManager 클래스에서 CTimer 클래스를 동적 할당 해준다.

게임로직이 실행되면, 가장 먼저 DeltaTime을 구해주고, 이후 실행되는 메소드들에 DeltaTime을 전달한다.

 

CGameManager::Render()

텍스트로 현재 DeltaTime과 FPS를 계산해서

TextOutA 함수로 우측 상단에 출력해 보자.

  * 실수 출력은 멀티바이트 문자 집합으로만 가능하다.

 

 

 

< 결과 > 

 

 

 

GameFrameworkStepbyStep_DeltaTIme.zip
0.79MB

'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글

09. Vector2 구조체  (0) 2022.05.16
08. GameObject 상속 구조 짜기  (0) 2022.05.16
06. 화면 출력  (0) 2022.05.16
05. PeekMessage 함수와 Run() 루프  (0) 2022.05.15
04. crtdbg 헤더를 통한 메모리 누수 잡기  (0) 2022.05.15
'WIN32API FrameWork/한단계씩 직접 구현' 카테고리의 다른 글
  • 09. Vector2 구조체
  • 08. GameObject 상속 구조 짜기
  • 06. 화면 출력
  • 05. PeekMessage 함수와 Run() 루프
hyrule
hyrule
hyrule
C++ 프로그래밍 공부
hyrule
전체
오늘
어제
  • 분류 전체보기 (205)
    • C++기초 (50)
    • WIN32API FrameWork (109)
      • 한단계씩 직접 구현 (82)
      • 원본 (15)
      • 코드별 설명 개별저장(검색용) (12)
    • 자습 (21)
    • C++ TIPS (11)
    • 연습 노트 (3)
    • ETC (6)
    • DX2D StarCraft 모작 (1)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • Windows 11
  • notion
  • hello
  • C++
  • 스타크래프트
  • Tistory

최근 댓글

최근 글

hELLO · Designed By 정상우.
hyrule
07. DeltaTime
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.