add name of player under cursor in top right

This commit is contained in:
Evan
2024-11-30 19:13:20 -08:00
parent a7e82960d3
commit 8f3f9ee84a
5 changed files with 162 additions and 9 deletions
+13 -3
View File
@@ -1,4 +1,4 @@
import {EventBus, GameEvent} from "../core/EventBus";
import { EventBus, GameEvent } from "../core/EventBus";
export class MouseUpEvent implements GameEvent {
@@ -15,6 +15,13 @@ export class MouseDownEvent implements GameEvent {
) { }
}
export class MouseMoveEvent implements GameEvent {
constructor(
public readonly x: number,
public readonly y: number,
) { }
}
export class ContextMenuEvent implements GameEvent {
constructor(
public readonly x: number,
@@ -56,11 +63,14 @@ export class InputHandler {
initialize() {
this.canvas.addEventListener("pointerdown", (e) => this.onPointerDown(e));
this.canvas.addEventListener("pointerup", (e) => this.onPointerUp(e));
this.canvas.addEventListener("wheel", (e) => this.onScroll(e), {passive: false});
this.canvas.addEventListener("wheel", (e) => this.onScroll(e), { passive: false });
this.canvas.addEventListener('pointermove', this.onPointerMove.bind(this));
this.canvas.addEventListener('contextmenu', (e: MouseEvent) => {
this.onContextMenu(e);
});
this.canvas.addEventListener('pointermove', (e) => {
this.eventBus.emit(new MouseMoveEvent(e.clientX, e.clientY))
});
this.pointers.clear()
}
@@ -152,7 +162,7 @@ export class InputHandler {
return Math.sqrt(dx * dx + dy * dy);
}
private getPinchCenter(): {x: number, y: number} {
private getPinchCenter(): { x: number, y: number } {
const pointerEvents = Array.from(this.pointers.values());
return {
x: (pointerEvents[0].clientX + pointerEvents[1].clientX) / 2,
+11 -1
View File
@@ -1,4 +1,4 @@
import { Game } from "../../core/game/Game";
import { Game, PlayerInfo } from "../../core/game/Game";
import { NameLayer } from "./layers/NameLayer";
import { TerrainLayer } from "./layers/TerrainLayer";
import { TerritoryLayer } from "./layers/TerritoryLayer";
@@ -16,6 +16,7 @@ import { UIState } from "./UIState";
import { BuildMenu } from "./layers/radial/BuildMenu";
import { UnitLayer } from "./layers/UnitLayer";
import { StructureLayer } from "./layers/StructureLayer";
import { PlayerInfoOverlay } from "./layers/PlayerInfoOverlay";
export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer {
@@ -58,6 +59,14 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus:
eventsDisplay.game = game
eventsDisplay.clientID = clientID
const playerInfo = document.querySelector('player-info-overlay') as PlayerInfoOverlay
if (!(playerInfo instanceof PlayerInfoOverlay)) {
console.error('player info overlay not found')
}
playerInfo.eventBus = eventBus
playerInfo.clientID = clientID
playerInfo.transform = transformHandler
const layers: Layer[] = [
new TerrainLayer(game),
@@ -70,6 +79,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus:
new RadialMenu(eventBus, game, transformHandler, clientID, emojiTable as EmojiTable, buildMenu, uiState),
leaderboard,
controlPanel,
playerInfo
]
return new GameRenderer(game, eventBus, canvas, transformHandler, uiState, layers)
@@ -0,0 +1,134 @@
import { LitElement, html, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { Layer } from './Layer';
import { Game, Player } from '../../../core/game/Game';
import { ClientID } from '../../../core/Schemas';
import { EventBus } from '../../../core/EventBus';
import { TransformHandler } from '../TransformHandler';
import { MouseMoveEvent } from '../../InputHandler';
@customElement('player-info-overlay')
export class PlayerInfoOverlay extends LitElement implements Layer {
private game: Game;
public clientID: ClientID;
public eventBus: EventBus;
public transform: TransformHandler
@state()
private _playerName: string = '';
@state()
private _isVisible: boolean = false;
init(game: Game) {
this.game = game;
this.eventBus.on(MouseMoveEvent, e => this.onMouseEvent(e))
}
private onMouseEvent(event: MouseMoveEvent) {
this._isVisible = false
const worldCoord = this.transform.screenToWorldCoordinates(event.x, event.y)
if (!this.game.isOnMap(worldCoord)) {
return
}
const owner = this.game.tile(worldCoord).owner()
if (!owner.isPlayer()) {
return
}
const myPlayer = this.game.playerByClientID(this.clientID);
if (myPlayer == null) {
return;
}
if (owner == myPlayer) {
return
}
this._isVisible = true
this._playerName = owner.name()
}
tick() {
}
renderLayer(context: CanvasRenderingContext2D) {
// Render any necessary canvas elements
}
shouldTransform(): boolean {
return false;
}
setVisible(visible: boolean) {
this._isVisible = visible;
this.requestUpdate();
}
static styles = css`
:host {
display: block;
}
.player-info {
position: fixed;
top: 10px;
right: 10px;
z-index: 9999;
background-color: rgba(30, 30, 30, 0.7);
padding: 8px 12px;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(5px);
transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;
color: white;
font-size: 14px;
min-width: 120px;
text-align: left;
font-size: 18px;
}
.hidden {
opacity: 0;
visibility: hidden;
}
.player-name {
font-weight: bold;
margin-bottom: 4px;
}
.status {
font-size: 12px;
opacity: 0.8;
}
.status.alive {
color: #4CAF50;
}
.status.dead {
color: #f44336;
}
@media (max-width: 768px) {
.player-info {
top: 5px;
right: 5px;
padding: 6px 10px;
font-size: 12px;
min-width: 100px;
}
.status {
font-size: 10px;
}
}
`;
render() {
return html`
<div class="player-info ${this._isVisible ? '' : 'hidden'}">
<div class="player-name">${this._playerName}</div>
</div>
`;
}
}
+1
View File
@@ -84,6 +84,7 @@
<control-panel></control-panel>
<events-display></events-display>
<build-menu></build-menu>
<player-info-overlay></player-info-overlay>
<script>
window.addEventListener('DOMContentLoaded', (event) => {