import { AssetPreloaderService } from "../../../assetPreloaderService"; import { SplashComponent } from "../../splash/splash.component"; import { SimMain } from "../sim/SimMain"; import { VisLevel } from "./VisLevel"; export class VisMain { canvas: HTMLCanvasElement; context: CanvasRenderingContext2D; wallPattern: CanvasPattern; visLevel: VisLevel; simMain: SimMain; private startTimestamp: number = 0; private active: boolean = true; private ready: boolean = false; private gap: number = 0; assets: AssetPreloaderService; constructor(simMain: SimMain, assets: AssetPreloaderService, canvas: HTMLCanvasElement) { this.assets = assets; this.simMain = simMain; this.canvas = canvas; this.context = this.canvas.getContext("2d")!; this.context.globalCompositeOperation = "source-over"; this.wallPattern = this.createPattern(assets.getImage("wall.png"), 48); this.visLevel = new VisLevel(this, this.simMain, this.simMain.gdRoot, assets); const host = this; requestAnimationFrame(function step(timestamp) { host.step(timestamp); }); } private createPattern(image: HTMLImageElement, size: number): CanvasPattern { const tempCanvas = document.createElement("canvas"); const tempContext = tempCanvas.getContext("2d")!; tempCanvas.width = size; tempCanvas.height = size; tempContext.drawImage(image, 0, 0, image.width, image.height, 0, 0, size, size); return this.context.createPattern(tempCanvas, 'repeat')!; } private step(timestamp: number) { if (!this.active) { return; } const host = this; requestAnimationFrame((timestamp: number) => { host.step(timestamp); }); if (!this.startTimestamp) { this.startTimestamp = timestamp; } const simLevel = this.simMain.currentLevel; if (!simLevel) { return; } let targetStep = (timestamp - this.startTimestamp) * this.simMain.gdRoot.simulation.stepsPerSecond / 1000 - this.gap; if (simLevel.paused) { this.gap += targetStep - simLevel.currentStep; targetStep = simLevel.currentStep; } this.simMain.executeUntilStep(targetStep); this.visLevel.updateEveryFrame(targetStep); this.onRender(); }; public onResized() { const gameHost = document.getElementById("game-host") as HTMLDivElement; const width = gameHost.clientWidth; const height = gameHost.clientHeight; const ratio = window.devicePixelRatio; this.canvas.width = width * ratio; this.canvas.height = height * ratio; this.canvas.style.width = width + "px"; this.canvas.style.height = height + "px"; this.context.scale(ratio, ratio); this.visLevel.updateSize(); }; private onRender() { this.clear(); const ctx = this.context; ctx.font = "12px Tahoma"; const simLevel = this.simMain.currentLevel; if (!!simLevel) { if (!this.ready) { this.onResized(); this.ready = true; } this.visLevel.draw(); } }; private clear() { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } private stop() { this.active = false; } }