107 lines
3.4 KiB
TypeScript
107 lines
3.4 KiB
TypeScript
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;
|
|
}
|
|
}
|