2D Game Engine

Czas i pętla gry

Time to jedyne źródło deltaTime w silniku. Clamp, timeScale, krok stały i stan czasu — z przykładami slow motion i fixed update.

Jedno źródło czasu#

Time to jedyne źródło deltaTime w silniku. Nie ma drugiej pętli requestAnimationFrame — adapter przekazuje surowy czas klatki, a Time go clampuje i skaluje.

text
deltaTime = min(rawDeltaMs / 1000, maxDeltaTime) × timeScale

API#

ts
get elapsed()
get gameTime()
get realElapsed()
get deltaTime()
get realDeltaTime()
get rawDeltaTime()
get frame()
get isPaused()
get timeScale()
get maxDeltaTime()
get fixedDelta()
get fixedAlpha()
get isClamped()
get pendingFixedSteps()

update(rawDeltaMs: number): void
setTimeScale(value: number): this
setFixedStep(hz: number, maxSteps = 5): this
consumeFixedStep(): boolean
pause(): void
resume(): void
reset(): void
toState(): TimeState
WłaściwośćZnaczenie
elapsed / gameTimeSekundy gry (skalowane przez timeScale)
realElapsedSekundy rzeczywiste
deltaTimeKlatka gry po clampie i timeScale
realDeltaTimeKlatka po clampie, bez timeScale
rawDeltaTimeSurowa klatka z adaptera
isClampedKlatka została obcięta (np. po powrocie z innej karty)

Clamp i powrót z innej karty#

Gdy gracz wraca po minucie z innej karty, surowa klatka mogłaby wynosić 60 s — fizyka eksploduje. maxDeltaTime (domyślnie 0.1 s) ucina skok:

ts
update(dt: number) {
  if (this.getTime().isClamped) {
    this.getLogger().info('Klatka obcięta — powrót z tła')
  }
  this.player.translate(this.speed * dt, 0)
}

Krok stały (fixed step)#

Fizyka i logika wymagająca determinizmu powinny działać w fixedUpdate, nie w update:

ts
const engine = createEngine({
  parent: 'app',
  fixedStep: { hz: 60, maxSteps: 5 }
})
ts
class GameScene extends Scene {
  fixedUpdate(fixedDelta: number) {
    this.getPhysics().setVelocity(this.player, this.vx, this.vy)
  }

  update(dt: number) {
    const alpha = this.getTime().fixedAlpha
    this.camera.smoothTo(this.player.x, alpha)
  }
}
  • fixedDelta to stały krok (np. 1/60).
  • fixedAlpha to interpolacja między krokami — użyj jej do płynnego renderu.
  • maxSteps ogranicza nadganianie po lagi (domyślnie 5), więc spirala śmierci nie zjada klatki.

Slow motion i przyspieszenie#

ts
class GameScene extends Scene {
  update() {
    const input = this.getInput()
    if (input.isActionPressed('time-slow')) this.getTime().setTimeScale(0.3)
    if (input.isActionPressed('time-fast')) this.getTime().setTimeScale(2)
    if (input.isActionPressed('time-normal')) this.getTime().setTimeScale(1)
  }
}

Wskazówka

UI i liczniki czasu rzeczywistego (np. czas sesji) opieraj na realElapsed, nie na elapsed — inaczej slow motion zwolni też zegar, który nie powinien zwalniać.

Pauza#

ts
engine.pause()
engine.getTime().isPaused
engine.resume()

Pauza zatrzymuje czas gry i audio. Time.reset() zeruje liczniki — przydatne przy restarcie poziomu bez restartu silnika.