ticker

@webgamelibs/ticker

프레임 기반 게임 루프를 간단하게 관리할 수 있는 Ticker 클래스입니다. requestAnimationFrame 기반으로 실행되며, 선택적으로 FPS 제한(fps cap)을 적용할 수 있습니다.

설치

yarn add @webgamelibs/ticker
# 또는
npm install @webgamelibs/ticker

타입 정의(.d.ts)가 포함되어 있으므로 TypeScript에서 바로 사용 가능합니다.

사용법

import { Ticker } from '@webgamelibs/ticker'

const ticker = new Ticker((deltaTime) => {
  // deltaTime: 초 단위 경과 시간 (float)
  console.log(`프레임당 경과시간: ${deltaTime.toFixed(3)}s`)
})

// FPS 제한 적용
ticker.setFpsCap(60)

// FPS 제한 해제
ticker.disableFpsCap()

// 더 이상 필요 없을 때 루프 종료
ticker.remove()

생성자

new Ticker(onTick: (deltaTime: number) => void, fps?: number)

메서드

메서드 설명
setFpsCap(fps) FPS 제한을 동적으로 변경합니다. 0 이하의 값을 넣으면 자동으로 제한이 해제됩니다.
disableFpsCap() FPS 제한을 해제합니다.
remove() 내부 requestAnimationFrame을 취소하고 Ticker를 종료합니다.

FPS Cap 동작 방식

오류 처리

const ticker = new Ticker(() => {
  throw new Error('테스트용 에러')
})
// 콘솔에 에러가 표시되지만 루프는 계속 동작합니다.

탭 비활성화 시 큰 deltaTime 처리

브라우저 탭이 비활성화되면 requestAnimationFrame 호출 간격이 길어져 복귀 시 큰 deltaTime이 발생할 수 있습니다. 이 값은 기본적으로 클램프되지 않습니다. 필요하다면 직접 제한하세요.

const MAX_DT = 1 / 15 // 최소 15FPS 보장
const ticker = new Ticker((dt) => {
  update(Math.min(dt, MAX_DT))
})

테스트

이 패키지는 Jest 환경에서 테스트됩니다.

yarn add --dev jest ts-jest @types/jest jest-environment-jsdom

간단한 예시 테스트 (전체 예시는 src/ticker.test.ts 참고):

import { Ticker } from './ticker'

test('Ticker는 deltaTime을 onTick에 전달한다', () => {
  const onTick = jest.fn()
  const ticker = new Ticker(onTick)
  
  // requestAnimationFrame 모킹 후 시간 진행 시뮬레이션
  // ...
  
  ticker.remove()
  expect(onTick).toHaveBeenCalled()
})

라이선스

MIT License