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:
parent
3c4d77711e
commit
2fe3618926
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue