64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import { Doodler } from "@bearmetal/doodler";
|
|
import { StateMachine } from "./state/machine.ts";
|
|
import { getContextItem } from "./lib/context.ts";
|
|
|
|
export class GameLoop<T> {
|
|
lastTime: number;
|
|
running: boolean;
|
|
targetFps: number;
|
|
|
|
constructor(targetFps: number = 60) {
|
|
this.lastTime = performance.now();
|
|
this.running = false;
|
|
this.targetFps = targetFps;
|
|
}
|
|
|
|
async start(state: StateMachine<T>) {
|
|
if (this.running) return;
|
|
this.running = true;
|
|
this.lastTime = performance.now();
|
|
|
|
while (this.running) {
|
|
const currentTime = performance.now();
|
|
const deltaTime = (currentTime - this.lastTime) / 1000; // Convert to seconds
|
|
this.lastTime = currentTime;
|
|
|
|
try {
|
|
// Wait for state update to complete before continuing
|
|
await state.update(deltaTime);
|
|
} catch (error) {
|
|
console.error("Error in game loop:", error);
|
|
this.stop();
|
|
break;
|
|
}
|
|
|
|
// Use setTimeout to prevent immediate loop continuation
|
|
// and allow other tasks to run
|
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
}
|
|
}
|
|
|
|
stop() {
|
|
this.running = false;
|
|
}
|
|
}
|
|
|
|
// // Usage example:
|
|
// const gameState = {
|
|
// update: async (deltaTime) => {
|
|
// console.log(`Updating with delta time: ${deltaTime.toFixed(3)}s`);
|
|
// // Simulate some async work
|
|
// await new Promise(resolve => setTimeout(resolve, 16)); // ~60fps
|
|
// }
|
|
// };
|
|
|
|
// // Create and start the loop
|
|
// const loop = new GameLoop();
|
|
// loop.start(gameState);
|
|
|
|
// // Stop the loop after 5 seconds (example)
|
|
// setTimeout(() => {
|
|
// loop.stop();
|
|
// console.log('Loop stopped');
|
|
// }, 5000);
|