WWolves Den

개발 · 출시 · 약 3분

게임의 한 프레임: 입력, 상태 갱신, 화면 출력

게임을 움직이는 그림으로 바라보되, 게임 규칙과 렌더링을 구분하고 프레임 속도에 흔들리지 않는 갱신 흐름을 이해합니다.

Wolfgadeok · 업데이트

움직이는 그림 뒤에는 게임 상태가 있다

애니메이션과 게임은 연속된 화면을 보여준다는 공통점이 있습니다. 하지만 게임에서는 플레이어의 입력과 규칙에 따라 다음 상태가 결정됩니다. 화면에 보이는 움직임만으로 구조를 생각하면 입력이나 충돌 판정을 어디에 넣어야 하는지 혼란스러워집니다. 먼저 플레이어의 위치, 체력, 몬스터 상태 같은 데이터가 있고, 화면은 그 상태를 관찰하는 창이라고 나누어 생각해 봅시다.

예를 들어 오른쪽 이동키를 누르면 입력 처리기가 이동 의도를 만듭니다. 게임 규칙은 벽에 부딪히는지 확인하고 허용된 위치로 캐릭터를 이동시킵니다. 애니메이션 시스템은 이동 속도에 맞는 걷기 자세를 선택하고, 렌더러는 캐릭터와 배경을 그립니다. 걷기 그림을 재생하는 것과 실제 위치를 바꾸는 일은 관련 있지만 같은 작업은 아닙니다.

프레임마다 같은 거리를 움직이면 안 되는 이유

한 번 갱신할 때 x에 3을 더하면 초당 30번 갱신하는 환경에서는 90, 120번 갱신하는 환경에서는 360만큼 이동합니다. 숫자를 아주 작게 바꾸어도 컴퓨터마다 속도가 달라지는 구조는 그대로입니다. 초당 이동 속도를 정한 뒤 경과 시간 dt를 곱해야 합니다. 아래는 원리를 보여주는 의사 코드이며 충돌, 입력 정규화, 일시 정지 처리는 생략했습니다.

렌더링 횟수와 시뮬레이션 갱신 횟수도 반드시 같을 필요는 없습니다. 고정 간격으로 게임 규칙을 계산하고 두 상태 사이를 보간해 그릴 수도 있습니다. 반대로 가변 dt를 쓰는 작은 예제라면 창을 오래 멈췄다가 돌아왔을 때 한 번에 크게 이동하지 않도록 긴 시간 간격의 처리 정책을 정해야 합니다.

예제 · text

매 프레임:
    입력 의도 = 입력 읽기()
    dt = 이전 갱신 이후 경과한 초
    후보 위치 = 현재 위치 + 이동 방향 * 초당 속도 * dt
    현재 위치 = 충돌 규칙으로 후보 위치 보정()
    애니메이션 상태 갱신()
    현재 상태를 그리기()

FPS 숫자보다 체감 흐름을 확인하기

60 FPS보다 높은 화면 갱신도 표시 장치와 입력 지연 조건에 따라 의미가 있습니다. 반대로 평균 FPS가 높아도 간헐적으로 한 프레임이 오래 걸리면 끊김을 느낍니다. ‘60 이상은 무의미하다’거나 ‘게임은 보통 30~40이면 된다’는 기준을 모든 게임에 적용하지 않습니다. 목표 기기에서 프레임 시간과 입력 반응을 함께 확인하는 편이 낫습니다.

실습에서는 30과 60으로 갱신 제한을 바꾸어 같은 키를 같은 시간 누른 뒤 이동 거리를 비교해 보세요. 입력이 없을 때도 적의 이동과 애니메이션은 계속되어야 하지만, 최소화된 창에서 의미 없이 최대 속도로 그릴 이유는 없습니다. 실행 중, 일시 정지, 백그라운드 상태의 정책을 구분하면 게임의 형태를 유지하면서 불필요한 일을 줄일 수 있습니다.

참고 자료

예제는 학습용이며, 모든 환경에서 실행 검증된 완성 프로젝트는 아닙니다. 적용 전 사용 중인 버전과 프로젝트 환경에서 동작을 확인하세요.