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
This commit is contained in:
CenTdemeern1 2024-10-28 17:52:08 +01:00
parent 3c4d77711e
commit 2fe3618926
2 changed files with 18 additions and 17 deletions

View file

@ -557,7 +557,7 @@ let bgmNodes: ReturnType<typeof sound.createSourceNode> | null = null;
let renderer: Matter.Render | null = null; let renderer: Matter.Render | null = null;
let monoTextures: Record<string, Blob> = {}; let monoTextures: Record<string, Blob> = {};
let monoTextureUrls: Record<string, string> = {}; let monoTextureUrls: Record<string, string> = {};
let tickRaf: number | null = null; let tickInterval: number | null = null;
let game = new DropAndFusionGame({ let game = new DropAndFusionGame({
seed: seed, seed: seed,
gameMode: props.gameMode, 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() { function tick() {
const hasNextTick = game.tick(); const hasNextTick = game.tick();
if (hasNextTick) { if (!hasNextTick) stopTicking();
tickRaf = window.requestAnimationFrame(tick);
} else {
tickRaf = null;
}
} }
function tickReplay() { function tickReplay() {
@ -700,11 +707,7 @@ function tickReplay() {
if (!hasNextTick) break; if (!hasNextTick) break;
} }
if (hasNextTick) { if (!hasNextTick) stopTicking();
tickRaf = window.requestAnimationFrame(tickReplay);
} else {
tickRaf = null;
}
} }
async function start() { async function start() {
@ -716,7 +719,7 @@ async function start() {
}); });
Matter.Render.run(renderer); Matter.Render.run(renderer);
game.start(); game.start();
window.requestAnimationFrame(tick); startTicking(tick);
gameLoaded.value = true; gameLoaded.value = true;
@ -803,9 +806,7 @@ function reset() {
function dispose() { function dispose() {
game.dispose(); game.dispose();
if (renderer) Matter.Render.stop(renderer); if (renderer) Matter.Render.stop(renderer);
if (tickRaf) { stopTicking();
window.cancelAnimationFrame(tickRaf);
}
} }
function backToTitle() { function backToTitle() {
@ -829,7 +830,7 @@ function replay() {
}); });
Matter.Render.run(renderer); Matter.Render.run(renderer);
game.start(); game.start();
window.requestAnimationFrame(tickReplay); startTicking(tickReplay);
}); });
} }

View file

@ -51,7 +51,7 @@ export class DropAndFusionGame extends EventEmitter<{
public readonly DROP_COOLTIME = 30; // frame public readonly DROP_COOLTIME = 30; // frame
public readonly PLAYAREA_MARGIN = 25; public readonly PLAYAREA_MARGIN = 25;
private STOCK_MAX = 4; private STOCK_MAX = 4;
private TICK_DELTA = 1000 / 60; // 60fps public readonly TICK_DELTA = 1000 / 60; // 60fps
public frame = 0; public frame = 0;
public engine: Matter.Engine; public engine: Matter.Engine;