hit space bar for alternate view

This commit is contained in:
Evan
2024-12-19 16:17:07 -08:00
parent 66fbe8e6b4
commit 17d75324f8
7 changed files with 131 additions and 32 deletions
+4 -2
View File
@@ -243,14 +243,16 @@
* store and archive player cookies DONE 12/17/2024
* make ips less precise for user safety DONE 12/17/2024
* send client logs back to server DONE 12/18/2024
* render more info in info overlay
* render more info in info overlay DONE 12/19/2024
* create alternate view for freinds enemies DONE 12/19/2024
* give naval units health
* create more prominant discord link
* right click brings up player info menu
* create new view for enemies & personal units
* send client logs back to server DONE 12/17/2024
* make info panel merge with X, display more info
* right click brings up player info menu
* seperate server config from client config
* give naval units health
* bug: player names not updating sometimes
* make player editeable configs
* couldn't scroll left on build menu to deploy bombs (mobile)
+25
View File
@@ -44,6 +44,10 @@ export class DragEvent implements GameEvent {
) { }
}
export class AlternateViewEvent implements GameEvent {
constructor(public readonly alternateView: boolean) { }
}
export class InputHandler {
private lastPointerX: number = 0;
@@ -58,6 +62,8 @@ export class InputHandler {
private pointerDown: boolean = false
private alternateView = false
constructor(private canvas: HTMLCanvasElement, private eventBus: EventBus) { }
initialize() {
@@ -72,6 +78,25 @@ export class InputHandler {
this.eventBus.emit(new MouseMoveEvent(e.clientX, e.clientY))
});
this.pointers.clear()
window.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
e.preventDefault(); // Prevent page scrolling
if (!this.alternateView) {
this.alternateView = true
this.eventBus.emit(new AlternateViewEvent(true))
}
}
});
window.addEventListener('keyup', (e) => {
if (e.code === 'Space') {
e.preventDefault();
this.alternateView = false
this.eventBus.emit(new AlternateViewEvent(false))
}
});
}
private onPointerDown(event: PointerEvent) {
+1 -1
View File
@@ -75,7 +75,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus:
new TerrainLayer(game),
new TerritoryLayer(game, eventBus),
new StructureLayer(game, eventBus),
new UnitLayer(game, eventBus),
new UnitLayer(game, eventBus, clientID),
new NameLayer(game, game.config().theme(), transformHandler, clientID),
new UILayer(eventBus, game, clientID, transformHandler),
eventsDisplay,
+79 -26
View File
@@ -1,10 +1,17 @@
import { Colord } from "colord";
import { Theme } from "../../../core/configuration/Config";
import { Unit, UnitEvent, Cell, Game, Tile, UnitType } from "../../../core/game/Game";
import { Unit, UnitEvent, Cell, Game, Tile, UnitType, Player } from "../../../core/game/Game";
import { bfs, dist, euclDist } from "../../../core/Util";
import { Layer } from "./Layer";
import { EventBus } from "../../../core/EventBus";
import { consolex } from "../../../core/Consolex";
import { AlternateViewEvent } from "../../InputHandler";
import { ClientID } from "../../../core/Schemas";
enum Relationship {
Self,
Ally,
Enemy
}
export class UnitLayer implements Layer {
private canvas: HTMLCanvasElement;
@@ -14,7 +21,12 @@ export class UnitLayer implements Layer {
private theme: Theme = null;
constructor(private game: Game, private eventBus: EventBus) {
private alternateView = false
private myPlayer: Player | null = null
constructor(private game: Game, private eventBus: EventBus, private clientID: ClientID) {
this.theme = game.config().theme();
}
@@ -24,6 +36,9 @@ export class UnitLayer implements Layer {
}
tick() {
if (this.myPlayer == null) {
this.myPlayer = this.game.playerByClientID(this.clientID)
}
}
init(game: Game) {
@@ -34,6 +49,7 @@ export class UnitLayer implements Layer {
this.canvas.height = this.game.height();
this.eventBus.on(UnitEvent, e => this.onUnitEvent(e));
this.eventBus.on(AlternateViewEvent, e => this.onAlternativeViewEvent(e))
}
renderLayer(context: CanvasRenderingContext2D) {
@@ -46,6 +62,31 @@ export class UnitLayer implements Layer {
);
}
onAlternativeViewEvent(event: AlternateViewEvent) {
this.alternateView = event.alternateView
this.redraw()
}
redraw() {
for (const unit of this.game.units()) {
this.onUnitEvent(new UnitEvent(unit, unit.tile()))
}
}
private relationship(unit: Unit): Relationship {
if (this.myPlayer == null) {
return Relationship.Enemy
}
if (this.myPlayer == unit.owner()) {
return Relationship.Self
}
if (this.myPlayer.isAlliedWith(unit.owner())) {
return Relationship.Ally
}
return Relationship.Enemy
}
onUnitEvent(event: UnitEvent) {
switch (event.unit.type()) {
case UnitType.TransportShip:
@@ -71,6 +112,7 @@ export class UnitLayer implements Layer {
}
private handleDestroyerEvent(event: UnitEvent) {
const rel = this.relationship(event.unit)
bfs(event.oldTile, euclDist(event.oldTile, 4)).forEach(t => {
this.clearCell(t.cell());
});
@@ -78,12 +120,13 @@ export class UnitLayer implements Layer {
return
}
bfs(event.unit.tile(), euclDist(event.unit.tile(), 4))
.forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
bfs(event.unit.tile(), dist(event.unit.tile(), 3))
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
}
private handleBattleshipEvent(event: UnitEvent) {
const rel = this.relationship(event.unit)
bfs(event.oldTile, euclDist(event.oldTile, 6)).forEach(t => {
this.clearCell(t.cell());
});
@@ -91,48 +134,52 @@ export class UnitLayer implements Layer {
return
}
bfs(event.unit.tile(), euclDist(event.unit.tile(), 5))
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
bfs(event.unit.tile(), dist(event.unit.tile(), 4))
.forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
bfs(event.unit.tile(), euclDist(event.unit.tile(), 1))
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
}
private handleShellEvent(event: UnitEvent) {
const rel = this.relationship(event.unit)
this.clearCell(event.oldTile.cell())
if (!event.unit.isActive()) {
return
}
this.paintCell(event.unit.tile().cell(), this.theme.borderColor(event.unit.owner().info()), 255)
this.paintCell(event.unit.tile().cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255)
}
private handleNuke(event: UnitEvent) {
const rel = this.relationship(event.unit)
bfs(event.oldTile, euclDist(event.oldTile, 2)).forEach(t => {
this.clearCell(t.cell());
});
if (event.unit.isActive()) {
bfs(event.unit.tile(), euclDist(event.unit.tile(), 2))
.forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
}
}
private handleTradeShipEvent(event: UnitEvent) {
const rel = this.relationship(event.unit)
bfs(event.oldTile, euclDist(event.oldTile, 3)).forEach(t => {
this.clearCell(t.cell());
});
if (event.unit.isActive()) {
bfs(event.unit.tile(), dist(event.unit.tile(), 2))
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
}
if (event.unit.isActive()) {
bfs(event.unit.tile(), dist(event.unit.tile(), 1))
.forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
}
}
private handleBoatEvent(event: UnitEvent) {
const rel = this.relationship(event.unit)
if (!this.boatToTrail.has(event.unit)) {
this.boatToTrail.set(event.unit, new Set<Tile>());
}
@@ -142,30 +189,36 @@ export class UnitLayer implements Layer {
this.clearCell(t.cell());
});
if (event.unit.isActive()) {
try {
bfs(event.unit.tile(), dist(event.unit.tile(), 4)).forEach(
t => {
if (trail.has(t)) {
this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 150);
}
}
);
} catch {
consolex.log('uh oh')
for (const t of trail) {
this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 150);
}
bfs(event.unit.tile(), dist(event.unit.tile(), 2))
.forEach(t => this.paintCell(t.cell(), this.theme.borderColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
bfs(event.unit.tile(), dist(event.unit.tile(), 1))
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
} else {
trail.forEach(t => this.clearCell(t.cell()));
this.boatToTrail.delete(event.unit);
}
}
paintCell(cell: Cell, color: Colord, alpha: number) {
paintCell(cell: Cell, relationship: Relationship, color: Colord, alpha: number) {
this.clearCell(cell)
this.context.fillStyle = color.alpha(alpha / 255).toRgbString();
if (this.alternateView) {
switch (relationship) {
case Relationship.Self:
this.context.fillStyle = this.theme.selfColor().toRgbString()
break
case Relationship.Ally:
this.context.fillStyle = this.theme.allyColor().toRgbString()
break
case Relationship.Enemy:
this.context.fillStyle = this.theme.enemyColor().toRgbString()
break
}
} else {
this.context.fillStyle = color.alpha(alpha / 255).toRgbString();
}
this.context.fillRect(cell.x, cell.y, 1, 1);
}
+4
View File
@@ -84,5 +84,9 @@ export interface Theme {
backgroundColor(): Colord;
falloutColor(): Colord
font(): string;
// unit color for alternate view
selfColor(): Colord
allyColor(): Colord
enemyColor(): Colord
}
+3 -3
View File
@@ -25,9 +25,9 @@ export const devConfig = new class extends DefaultConfig {
lobbyLifetime(): number {
return 10 * 1000
}
// tradeShipSpawnRate(): number {
// return 10
// }
tradeShipSpawnRate(): number {
return 10
}
boatMaxDistance(): number {
return 5000
}
+15
View File
@@ -122,6 +122,11 @@ export const pastelTheme = new class implements Theme {
colord({ r: 170, g: 150, b: 170 }) // Dusty Rose
];
private _selfColor = colord({ r: 0, g: 255, b: 0 })
private _allyColor = colord({ r: 255, g: 255, b: 0 })
private _enemyColor = colord({ r: 255, g: 0, b: 0 })
playerInfoColor(id: PlayerID): Colord {
return colord({ r: 50, g: 50, b: 50 })
}
@@ -199,4 +204,14 @@ export const pastelTheme = new class implements Theme {
font(): string {
return "Overpass, sans-serif";
}
selfColor(): Colord {
return this._selfColor
}
allyColor(): Colord {
return this._allyColor
}
enemyColor(): Colord {
return this._enemyColor
}
}