refactor interface name layers

This commit is contained in:
evanpelle
2024-09-16 19:13:48 -07:00
parent aaa16683e1
commit b187ddf3f4
7 changed files with 43 additions and 36 deletions
+8 -11
View File
@@ -1,12 +1,9 @@
import {Colord} from "colord";
import {Cell, Game, PlayerEvent, Tile, TileEvent, Player, Execution, BoatEvent} from "../../core/Game";
import {Theme} from "../../core/configuration/Config";
import {DragEvent, ZoomEvent} from "../InputHandler";
import {Game} from "../../core/Game";
import {NameLayer} from "./layers/NameLayer";
import {TerrainLayer} from "./layers/TerrainLayer";
import {TerritoryLayer} from "./layers/TerritoryLayer";
import {ClientID} from "../../core/Schemas";
import {createCanvas, renderTroops} from "./Utils";
import {createCanvas} from "./Utils";
import {UILayer} from "./layers/UILayer";
import {EventBus} from "../../core/EventBus";
import {TransformHandler} from "./TransformHandler";
@@ -15,13 +12,13 @@ import {Layer} from "./layers/Layer";
export function createRenderer(game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer {
const canvas = createCanvas()
const transformHandler = new TransformHandler(game, eventBus, canvas.getBoundingClientRect())
const transformHandler = new TransformHandler(game, eventBus, canvas)
const layers: Layer[] = [
new TerrainLayer(game),
new TerritoryLayer(game, eventBus),
new NameLayer(game, game.config().theme()),
new UILayer(eventBus, game, game.config().theme(), clientID)
new NameLayer(game, game.config().theme(), transformHandler),
new UILayer(eventBus, game, game.config().theme(), clientID, transformHandler)
]
return new GameRenderer(game, eventBus, canvas, transformHandler, layers)
@@ -43,7 +40,7 @@ export class GameRenderer {
window.addEventListener('resize', () => this.resizeCanvas());
this.resizeCanvas();
this.transformHandler = new TransformHandler(this.game, this.eventBus, this.canvas.getBoundingClientRect())
this.transformHandler = new TransformHandler(this.game, this.eventBus, this.canvas)
requestAnimationFrame(() => this.renderGame());
}
@@ -66,7 +63,7 @@ export class GameRenderer {
this.layers.forEach(l => {
if (l.shouldTransform()) {
l.render(this.context, this.transformHandler)
l.render(this.context)
}
})
@@ -74,7 +71,7 @@ export class GameRenderer {
this.layers.forEach(l => {
if (!l.shouldTransform()) {
l.render(this.context, this.transformHandler)
l.render(this.context)
}
})
+8 -4
View File
@@ -7,13 +7,17 @@ export class TransformHandler {
private offsetX: number = -350
private offsetY: number = -200
constructor(private game: Game, private eventBus: EventBus, private boundingRect: DOMRect) {
constructor(private game: Game, private eventBus: EventBus, private canvas: HTMLCanvasElement) {
this.eventBus.on(ZoomEvent, (e) => this.onZoom(e))
this.eventBus.on(DragEvent, (e) => this.onMove(e))
}
boundingRect(): DOMRect {
return this.canvas.getBoundingClientRect()
}
width(): number {
return this.boundingRect.right
return this.boundingRect().width
}
handleTransform(context: CanvasRenderingContext2D) {
@@ -36,7 +40,7 @@ export class TransformHandler {
}
screenToWorldCoordinates(screenX: number, screenY: number): Cell {
const canvasRect = this.boundingRect;
const canvasRect = this.boundingRect();
const canvasX = screenX - canvasRect.left;
const canvasY = screenY - canvasRect.top;
@@ -78,7 +82,7 @@ export class TransformHandler {
// Clamp the scale to prevent extreme zooming
this.scale = Math.max(0.5, Math.min(20, this.scale));
const canvasRect = this.boundingRect
const canvasRect = this.boundingRect()
const canvasX = event.x - canvasRect.left;
const canvasY = event.y - canvasRect.top;
+1 -1
View File
@@ -3,6 +3,6 @@ import {TransformHandler} from "../TransformHandler"
export interface Layer {
init()
tick()
render(context: CanvasRenderingContext2D, transformHandler: TransformHandler)
render(context: CanvasRenderingContext2D)
shouldTransform(): boolean
}
+5 -15
View File
@@ -25,13 +25,10 @@ export class NameLayer implements Layer {
private refreshRate = 1000
private rand = new PseudoRandom(10)
private renderInfo: Map<Player, RenderInfo> = new Map()
private context: CanvasRenderingContext2D
private canvas: HTMLCanvasElement
private renders: RenderInfo[] = []
private seenPlayers: Set<Player> = new Set()
constructor(private game: Game, private theme: Theme) {
constructor(private game: Game, private theme: Theme, private transformHandler: TransformHandler) {
}
shouldTransform(): boolean {
@@ -40,14 +37,7 @@ export class NameLayer implements Layer {
public init() {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d');
this.canvas.style.position = 'fixed';
this.canvas.style.left = '0';
this.canvas.style.top = '0';
this.canvas.width = this.game.width();
this.canvas.height = this.game.height();
}
// TODO: remove tick, move this to render
@@ -80,12 +70,12 @@ export class NameLayer implements Layer {
}
}
public render(mainContex: CanvasRenderingContext2D, transformHandler: TransformHandler) {
const [upperLeft, bottomRight] = transformHandler.screenBoundingRect()
public render(mainContex: CanvasRenderingContext2D) {
const [upperLeft, bottomRight] = this.transformHandler.screenBoundingRect()
for (const render of this.renders) {
render.isVisible = this.isVisible(render, upperLeft, bottomRight)
if (render.player.isAlive() && render.isVisible && render.fontSize * transformHandler.scale > 10) {
this.renderPlayerInfo(render, mainContex, transformHandler.scale, upperLeft, bottomRight)
if (render.player.isAlive() && render.isVisible && render.fontSize * this.transformHandler.scale > 10) {
this.renderPlayerInfo(render, mainContex, this.transformHandler.scale, upperLeft, bottomRight)
}
}
}
+1 -1
View File
@@ -41,7 +41,7 @@ export class TerrainLayer implements Layer {
})
}
render(context: CanvasRenderingContext2D, transformHandler: TransformHandler) {
render(context: CanvasRenderingContext2D) {
context.drawImage(
this.canvas,
-this.game.width() / 2,
+1 -1
View File
@@ -50,7 +50,7 @@ export class TerritoryLayer implements Layer {
})
}
render(context: CanvasRenderingContext2D, transformHandler: TransformHandler) {
render(context: CanvasRenderingContext2D) {
this.renderTerritory()
this.context.putImageData(this.imageData, 0, 0);
context.drawImage(
+19 -3
View File
@@ -22,16 +22,16 @@ export class UILayer implements Layer {
private customMenu = document.getElementById('customMenu');
constructor(private eventBus: EventBus, private game: Game, private theme: Theme, private clientID: ClientID) {
constructor(private eventBus: EventBus, private game: Game, private theme: Theme, private clientID: ClientID, private transformHandler: TransformHandler) {
}
render(context: CanvasRenderingContext2D, transformHandler: TransformHandler) {
render(context: CanvasRenderingContext2D) {
if (!this.game.inSpawnPhase()) {
return
}
const barHeight = 15;
const barBackgroundWidth = transformHandler.width();
const barBackgroundWidth = this.transformHandler.width();
const ratio = this.game.ticks() / this.game.config().numSpawnPhaseTurns()
@@ -219,9 +219,25 @@ export class UILayer implements Layer {
}
private onRightClick(e: RightClickEvent) {
const cell = this.transformHandler.screenToWorldCoordinates(e.x, e.y)
const tile = this.game.tile(cell)
if (!tile.hasOwner()) {
return
}
const owner = tile.owner() as Player
if (owner.clientID() == this.clientID) {
return
}
this.customMenu!.style.display = 'block';
this.customMenu!.style.left = `${e.x}px`;
this.customMenu!.style.top = `${e.y}px`;
this.populateMenu([
{
label: "Request Alliance",
action: (): void => { },
}
])
}
private populateMenu(options: MenuOption[]) {