1
0
Fork 0
tsgames/src/common/game.ts

52 lines
1.6 KiB
TypeScript

import { formatError, formatErrorMessage } from "./errors";
import Input from "./input";
import { nextFrame } from "./utils";
type Setup<T> = () => Promise<T> | T;
type Frame<T> = (dt: number, state: T) => Promise<T | void> | T | void;
type GameMain = () => void;
export function gameLoop<T>(frame: Frame<T>): GameMain;
export function gameLoop<T>(setup: Setup<T>, frame: Frame<T>): GameMain;
export function gameLoop<T>(setupOrFrame: Setup<T> | Frame<T>, frame?: Frame<T>): GameMain {
return async () => {
let state: T;
try {
if (frame) {
state = await (setupOrFrame as Setup<T>)();
} else {
frame = setupOrFrame as Frame<T>;
state = {} as T;
}
} catch (e) {
console.error(formatError(e, 'Error in game setup'));
alert(formatErrorMessage(e));
return;
}
try {
let prevFrame = performance.now();
while (true) {
await nextFrame();
Input.updateKeys();
const now = performance.now();
const dt = (now - prevFrame) / 1000;
if (dt < 1) {
const newState = await frame(dt, state);
if (newState) {
state = newState;
}
}
prevFrame = performance.now();
}
} catch (e) {
console.error(formatError(e, 'Error in game loop'));
alert(formatErrorMessage(e));
return;
}
}
};