Files
OpenFrontIO/src/client/graphics/GameRenderer.ts
T
2024-10-11 20:48:55 -07:00

106 lines
3.2 KiB
TypeScript

import {Game} from "../../core/game/Game";
import {NameLayer} from "./layers/NameLayer";
import {TerrainLayer} from "./layers/TerrainLayer";
import {TerritoryLayer} from "./layers/TerritoryLayer";
import {ClientID} from "../../core/Schemas";
import {UILayer} from "./layers/UILayer";
import {EventBus} from "../../core/EventBus";
import {TransformHandler} from "./TransformHandler";
import {Layer} from "./layers/Layer";
import {EventsDisplay} from "./layers/EventsDisplay";
import {RadialMenu} from "./layers/radial/RadialMenu";
import {EmojiTable} from "./layers/radial/EmojiTable";
import {Leaderboard} from "./layers/Leaderboard";
export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer {
const transformHandler = new TransformHandler(game, eventBus, canvas)
const emojiTable = document.querySelector('emoji-table') as EmojiTable;
if (!emojiTable || !(emojiTable instanceof EmojiTable)) {
console.error('EmojiTable element not found in the DOM');
}
const leaderboard = document.querySelector('leader-board') as Leaderboard;
if (!emojiTable || !(leaderboard instanceof Leaderboard)) {
console.error('EmojiTable element not found in the DOM');
}
leaderboard.clientID = clientID
const layers: Layer[] = [
new TerrainLayer(game),
new TerritoryLayer(game, eventBus),
new NameLayer(game, game.config().theme(), transformHandler, clientID),
new UILayer(eventBus, game, clientID, transformHandler),
new EventsDisplay(eventBus, game, clientID),
new RadialMenu(eventBus, game, transformHandler, clientID, emojiTable as EmojiTable),
leaderboard,
]
return new GameRenderer(game, eventBus, canvas, transformHandler, layers)
}
export class GameRenderer {
private context: CanvasRenderingContext2D
constructor(private game: Game, private eventBus: EventBus, private canvas: HTMLCanvasElement, public transformHandler: TransformHandler, private layers: Layer[]) {
this.context = canvas.getContext("2d")
}
initialize() {
this.layers.forEach(l => l.init(this.game))
document.body.appendChild(this.canvas);
window.addEventListener('resize', () => this.resizeCanvas());
this.resizeCanvas();
this.transformHandler = new TransformHandler(this.game, this.eventBus, this.canvas)
requestAnimationFrame(() => this.renderGame());
}
resizeCanvas() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
//this.redraw()
}
renderGame() {
// Set background
this.context.fillStyle = this.game.config().theme().backgroundColor().toHex();
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
// Save the current context state
this.context.save();
this.transformHandler.handleTransform(this.context)
this.layers.forEach(l => {
if (l.shouldTransform()) {
l.renderLayer(this.context)
}
})
this.context.restore()
this.layers.forEach(l => {
if (!l.shouldTransform()) {
l.renderLayer(this.context)
}
})
requestAnimationFrame(() => this.renderGame());
}
tick() {
this.layers.forEach(l => l.tick())
}
resize(width: number, height: number): void {
this.canvas.width = Math.ceil(width / window.devicePixelRatio);
this.canvas.height = Math.ceil(height / window.devicePixelRatio);
}
}