create unit layer

This commit is contained in:
Evan
2024-11-09 13:32:25 -08:00
parent aea22f089c
commit 3ac8dbddc5
4 changed files with 123 additions and 42 deletions
+5 -4
View File
@@ -172,11 +172,12 @@
* rewrite EventsDisplay DONE 11/1/2024
* update Mena NPC locations DONE 11/1/2024
* create build menu DONE 11/3/2024
* add gold
* add troop/worker slider
* add battleship
* add gold DONE 11/4/2024
* add troop/worker slider DONE 11/4/2024
* create Unit layer DONE 11/9/2024
* create Unit interface
* add destroyer
* NPC has relations
* fix name rendering
* use twitter emojis
* private game shows how many players joined
* optimize sendBoat function
+2
View File
@@ -14,6 +14,7 @@ import { Leaderboard } from "./layers/Leaderboard";
import { ControlPanel } from "./layers/ControlPanel";
import { UIState } from "./UIState";
import { BuildMenu } from "./layers/radial/BuildMenu";
import { UnitLayer } from "./layers/UnitLayer";
export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer {
@@ -61,6 +62,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus:
const layers: Layer[] = [
new TerrainLayer(game),
new TerritoryLayer(game, eventBus),
new UnitLayer(game, eventBus),
new NameLayer(game, game.config().theme(), transformHandler, clientID),
new UILayer(eventBus, game, clientID, transformHandler),
eventsDisplay,
+3 -28
View File
@@ -1,5 +1,5 @@
import { PriorityQueue } from "@datastructures-js/priority-queue";
import {Boat, BoatEvent, Cell, Game, Player, Tile, TileEvent} from "../../../core/game/Game";
import { Cell, Game, Player, Tile, TileEvent } from "../../../core/game/Game";
import { PseudoRandom } from "../../../core/PseudoRandom";
import { Colord } from "colord";
import { bfs, dist } from "../../../core/Util";
@@ -17,17 +17,17 @@ export class TerritoryLayer implements Layer {
private random = new PseudoRandom(123)
private theme: Theme = null
private boatToTrail = new Map<Boat, Set<Tile>>()
constructor(private game: Game, eventBus: EventBus) {
this.theme = game.config().theme()
eventBus.on(TileEvent, e => this.tileUpdate(e))
eventBus.on(BoatEvent, e => this.boatEvent(e))
}
shouldTransform(): boolean {
return true
}
tick() {
}
@@ -62,31 +62,6 @@ export class TerritoryLayer implements Layer {
)
}
boatEvent(event: BoatEvent) {
if (!this.boatToTrail.has(event.boat)) {
this.boatToTrail.set(event.boat, new Set<Tile>())
}
const trail = this.boatToTrail.get(event.boat)
trail.add(event.oldTile)
bfs(event.oldTile, dist(event.oldTile, 3)).forEach(t => {
this.paintTerritory(t)
})
if (event.boat.isActive()) {
bfs(event.boat.tile(), dist(event.boat.tile(), 4)).forEach(
t => {
if (trail.has(t)) {
this.paintCell(t.cell(), this.theme.territoryColor(event.boat.owner().info()), 150)
}
}
)
bfs(event.boat.tile(), dist(event.boat.tile(), 2)).forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.boat.owner().info()), 255))
bfs(event.boat.tile(), dist(event.boat.tile(), 1)).forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.boat.owner().info()), 180))
} else {
trail.forEach(t => this.paintTerritory(t))
this.boatToTrail.delete(event.boat)
}
}
renderTerritory() {
let numToRender = Math.floor(this.tileToRenderQueue.size() / 10)
if (numToRender == 0) {
+103
View File
@@ -0,0 +1,103 @@
import { Colord } from "colord";
import { Theme } from "../../../core/configuration/Config";
import { Boat, BoatEvent, Cell, Game, Tile } from "../../../core/game/Game";
import { bfs, dist } from "../../../core/Util";
import { Layer } from "./Layer";
import { EventBus } from "../../../core/EventBus";
export class UnitLayer implements Layer {
private canvas: HTMLCanvasElement
private context: CanvasRenderingContext2D
private imageData: ImageData
private boatToTrail = new Map<Boat, Set<Tile>>()
private theme: Theme = null
constructor(private game: Game, private eventBus: EventBus) {
this.theme = game.config().theme()
}
shouldTransform(): boolean {
return true
}
tick() {
}
init(game: Game) {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext("2d")
this.imageData = this.context.getImageData(0, 0, this.game.width(), this.game.height())
this.canvas.width = this.game.width();
this.canvas.height = this.game.height();
this.context.putImageData(this.imageData, 0, 0);
this.initImageData()
this.eventBus.on(BoatEvent, e => this.onBoatEvent(e))
}
initImageData() {
this.game.forEachTile((tile) => {
const index = (tile.cell().y * this.game.width()) + tile.cell().x
const offset = index * 4
this.imageData.data[offset + 3] = 0
})
}
renderLayer(context: CanvasRenderingContext2D) {
this.context.putImageData(this.imageData, 0, 0);
context.drawImage(
this.canvas,
-this.game.width() / 2,
-this.game.height() / 2,
this.game.width(),
this.game.height()
)
}
onBoatEvent(event: BoatEvent) {
if (!this.boatToTrail.has(event.boat)) {
this.boatToTrail.set(event.boat, new Set<Tile>())
}
const trail = this.boatToTrail.get(event.boat)
trail.add(event.oldTile)
bfs(event.oldTile, dist(event.oldTile, 3)).forEach(t => {
this.clearCell(t.cell())
})
if (event.boat.isActive()) {
bfs(event.boat.tile(), dist(event.boat.tile(), 4)).forEach(
t => {
if (trail.has(t)) {
this.paintCell(t.cell(), this.theme.territoryColor(event.boat.owner().info()), 150)
}
}
)
bfs(event.boat.tile(), dist(event.boat.tile(), 2)).forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.boat.owner().info()), 255))
bfs(event.boat.tile(), dist(event.boat.tile(), 1)).forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.boat.owner().info()), 180))
} else {
trail.forEach(t => this.clearCell(t.cell()))
this.boatToTrail.delete(event.boat)
}
}
paintCell(cell: Cell, color: Colord, alpha: number) {
const index = (cell.y * this.game.width()) + cell.x
const offset = index * 4
this.imageData.data[offset] = color.rgba.r;
this.imageData.data[offset + 1] = color.rgba.g;
this.imageData.data[offset + 2] = color.rgba.b;
this.imageData.data[offset + 3] = alpha
}
clearCell(cell: Cell) {
const index = (cell.y * this.game.width()) + cell.x;
const offset = index * 4;
this.imageData.data[offset + 3] = 0; // Set alpha to 0 (fully transparent)
}
}