1
0
Fork 0
tsgames/src/games/zombies/index.ts

84 lines
2.2 KiB
TypeScript

import { createCanvas } from "@common/display/canvas";
import Spinner from "./spinner";
import type Entity from "./entity";
import { getRealPoint } from "@common/dom";
import { clamp, nextFrame } from "@common/utils";
import bgImg from './assets/bg.jpg';
import TileMap from "./tilemap";
import Inventory from "./inventory";
const MAP_SIZE = 12;
const MAP_PIXEL_SIZE = window.innerHeight;
const MAP_PADDING = 10;
const TILE_SIZE = (MAP_PIXEL_SIZE - MAP_PADDING * 2) / MAP_SIZE;
const SIDEBAR_SIZE = clamp((window.innerWidth - window.innerHeight) / 2, 300, 600);
const canvas = createCanvas(MAP_PIXEL_SIZE + SIDEBAR_SIZE * 2, MAP_PIXEL_SIZE);
const map = new TileMap(
[MAP_PADDING + SIDEBAR_SIZE, MAP_PADDING],
MAP_SIZE,
TILE_SIZE,
);
const spinner = new Spinner([MAP_PIXEL_SIZE + SIDEBAR_SIZE, 0], [SIDEBAR_SIZE, SIDEBAR_SIZE]);
const inventory = new Inventory(
map,
[0, 0],
[SIDEBAR_SIZE, MAP_PIXEL_SIZE],
);
const entities: Entity[] = [
spinner,
map,
inventory,
];
async function update(dt: number) {
entities.forEach(entity => entity.update(dt));
}
async function render(ctx: CanvasRenderingContext2D) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(bgImg, SIDEBAR_SIZE, 0, MAP_PIXEL_SIZE, MAP_PIXEL_SIZE);
entities.forEach(entity => entity.render(ctx));
}
async function onClick(e: MouseEvent) {
const point = getRealPoint(canvas, e);
entities.forEach(entity => entity.handleClick(point.x, point.y));
}
async function onMouseMove(e: MouseEvent) {
const point = getRealPoint(canvas, e);
entities.forEach(entity => entity.handleMouseMove(point.x, point.y));
}
export default async function main() {
canvas.style.imageRendering = 'auto';
const ctx = canvas.getContext('2d');
spinner.addListener((a) => map.handleSpin(a));
canvas.addEventListener('click', onClick);
canvas.addEventListener('mousemove', onMouseMove);
if (ctx) {
let prevFrame = performance.now();
while (true) {
const now = await nextFrame();
const dt = (now - prevFrame) / 1000;
prevFrame = now;
update(dt);
render(ctx);
}
}
}