From 2fe3618926a78fae7a0b066ed05e6775e24513da Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Mon, 28 Oct 2024 17:52:08 +0100 Subject: [PATCH] bubble-game: Use setInterval instead of requestAnimationFrame This makes sure Misskey's Bubble Game always runs at a consistent rate, even when the monitor isn't 60hz --- .../src/pages/drop-and-fusion.game.vue | 33 ++++++++++--------- packages/misskey-bubble-game/src/game.ts | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index fb4d599c28..8d369101af 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -557,7 +557,7 @@ let bgmNodes: ReturnType | null = null; let renderer: Matter.Render | null = null; let monoTextures: Record = {}; let monoTextureUrls: Record = {}; -let tickRaf: number | null = null; +let tickInterval: number | null = null; let game = new DropAndFusionGame({ seed: seed, gameMode: props.gameMode, @@ -663,13 +663,20 @@ function getTextureImageUrl(mono: Mono) { } } +function startTicking(tickFunction: () => void) { + tickInterval = window.setInterval(tickFunction, game.TICK_DELTA); +} + +function stopTicking() { + if (tickInterval !== null) { + window.clearInterval(tickInterval); + tickInterval = null; + } +} + function tick() { const hasNextTick = game.tick(); - if (hasNextTick) { - tickRaf = window.requestAnimationFrame(tick); - } else { - tickRaf = null; - } + if (!hasNextTick) stopTicking(); } function tickReplay() { @@ -700,11 +707,7 @@ function tickReplay() { if (!hasNextTick) break; } - if (hasNextTick) { - tickRaf = window.requestAnimationFrame(tickReplay); - } else { - tickRaf = null; - } + if (!hasNextTick) stopTicking(); } async function start() { @@ -716,7 +719,7 @@ async function start() { }); Matter.Render.run(renderer); game.start(); - window.requestAnimationFrame(tick); + startTicking(tick); gameLoaded.value = true; @@ -803,9 +806,7 @@ function reset() { function dispose() { game.dispose(); if (renderer) Matter.Render.stop(renderer); - if (tickRaf) { - window.cancelAnimationFrame(tickRaf); - } + stopTicking(); } function backToTitle() { @@ -829,7 +830,7 @@ function replay() { }); Matter.Render.run(renderer); game.start(); - window.requestAnimationFrame(tickReplay); + startTicking(tickReplay); }); } diff --git a/packages/misskey-bubble-game/src/game.ts b/packages/misskey-bubble-game/src/game.ts index 7f230e39cb..ff43488c7d 100644 --- a/packages/misskey-bubble-game/src/game.ts +++ b/packages/misskey-bubble-game/src/game.ts @@ -51,7 +51,7 @@ export class DropAndFusionGame extends EventEmitter<{ public readonly DROP_COOLTIME = 30; // frame public readonly PLAYAREA_MARGIN = 25; private STOCK_MAX = 4; - private TICK_DELTA = 1000 / 60; // 60fps + public readonly TICK_DELTA = 1000 / 60; // 60fps public frame = 0; public engine: Matter.Engine;