don't render player info on top of exit button, render unit type

This commit is contained in:
Evan
2024-12-19 10:57:41 -08:00
parent 65cf2a7c19
commit 66fbe8e6b4
5 changed files with 151 additions and 109 deletions
+4
View File
@@ -242,6 +242,10 @@
* better error logging in server DONE 12/16/2024
* 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
* 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
+1
View File
@@ -68,6 +68,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus:
playerInfo.eventBus = eventBus
playerInfo.clientID = clientID
playerInfo.transform = transformHandler
playerInfo.game = game
const layers: Layer[] = [
+144 -104
View File
@@ -6,51 +6,64 @@ import { ClientID } from '../../../core/Schemas';
import { EventBus } from '../../../core/EventBus';
import { TransformHandler } from '../TransformHandler';
import { MouseMoveEvent } from '../../InputHandler';
import { dist, distSortUnit, euclideanDist, manhattanDist } from '../../../core/Util';
import { euclideanDist, distSortUnit } from '../../../core/Util';
import { renderNumber, renderTroops } from '../../Utils';
@customElement('player-info-overlay')
export class PlayerInfoOverlay extends LitElement implements Layer {
private game: Game;
public clientID: ClientID;
public eventBus: EventBus;
public transform: TransformHandler;
@property({ type: Object })
public game!: Game;
@property({ type: String })
public clientID!: ClientID;
@property({ type: Object })
public eventBus!: EventBus;
@property({ type: Object })
public transform!: TransformHandler;
@state()
private selectedType: "player" | "unit" | null = null
private player: Player | null = null;
@state()
private player: Player
@state()
private unit: Unit
private unit: Unit | null = null;
@state()
private _isVisible: boolean = false;
init(game: Game) {
this.game = game;
this.eventBus.on(MouseMoveEvent, e => this.onMouseEvent(e));
this.eventBus.on(MouseMoveEvent, (e: MouseMoveEvent) => this.onMouseEvent(e));
}
private onMouseEvent(event: MouseMoveEvent) {
this._isVisible = false;
this.setVisible(false);
this.unit = null;
this.player = null;
const worldCoord = this.transform.screenToWorldCoordinates(event.x, event.y);
if (!this.game.isOnMap(worldCoord)) {
return;
return;
}
const tile = this.game.tile(worldCoord);
let owner = tile.owner();
if (!owner.isPlayer()) {
if (tile.isLand()) {
return;
const owner = tile.owner();
if (owner.isPlayer()) {
this.player = owner;
this.setVisible(true);
} else if (!tile.isLand()) {
const units = this.game.units()
.filter(u => euclideanDist(worldCoord, u.tile().cell()) < 50)
.sort(distSortUnit(tile));
if (units.length > 0) {
this.unit = units[0];
this.setVisible(true);
}
const units = this.game.units().filter(u => euclideanDist(worldCoord, u.tile().cell()) < 50).sort(distSortUnit(tile));
if (units.length == 0) {
return;
}
owner = units[0].owner();
}
this._isVisible = true;
}
private onExitButtonClick() {
@@ -58,11 +71,14 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
}
tick() {
this.unit = this.unit
if (this.game.ticks() % 10 == 0) {
this.requestUpdate()
}
// Implementation for Layer interface
}
renderLayer(context: CanvasRenderingContext2D) {
// Render any necessary canvas elements
// Implementation for Layer interface
}
shouldTransform(): boolean {
@@ -74,47 +90,70 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
this.requestUpdate();
}
private myPlayer(): Player | null {
if (!this.game) {
return null;
}
return this.game.playerByClientID(this.clientID);
}
private renderPlayerInfo(player: Player) {
const isAlly = (this.myPlayer()?.isAlliedWith(player) || player == this.myPlayer()) ?? false;
return html`
<div class="info-content">
<div class="player-name ${isAlly ? 'ally' : ''}">${player.name()}</div>
<div class="type-label">Troops: ${renderTroops(player.troops())}</div>
<div class="type-label">Gold: ${renderNumber(player.gold())}</div>
</div>
`;
}
private renderUnitInfo(unit: Unit) {
const isAlly = (unit.owner() == this.myPlayer() || this.myPlayer()?.isAlliedWith(unit.owner())) ?? false;
return html`
<div class="info-content">
<div class="player-name ${isAlly ? 'ally' : ''}">${unit.owner().name()}</div>
<div class="unit-details">
<div class="type-label">${unit.type()}</div>
</div>
</div>
`
}
render() {
return html`
<div class="container">
<div class="controls">
<button class="exit-button" @click=${this.onExitButtonClick}>×</button>
</div>
<div class="player-info ${!this._isVisible ? 'hidden' : ''}">
${this.player != null ? this.renderPlayerInfo(this.player) : ''}
${this.unit != null ? this.renderUnitInfo(this.unit) : ''}
</div>
</div>
`;
}
static styles = css`
:host {
display: block;
}
.overlay-container {
.container {
position: fixed;
top: 10px;
right: 10px;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.controls {
position: relative;
display: flex;
justify-content: flex-end;
width: 40px; /* Same as button width */
margin-bottom: 10px;
}
.exit-button {
width: 40px;
height: 40px;
font-size: 20px;
font-weight: bold;
background-color: rgba(255, 0, 0, 0.4);
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s;
}
.exit-button:hover {
background-color: rgba(255, 0, 0, 0.5);
}
.exit-button:active {
background-color: rgba(255, 0, 0, 0.6);
align-self: flex-end;
margin-bottom: 4px;
z-index: 2;
}
.player-info {
background-color: rgba(30, 30, 30, 0.7);
padding: 8px 12px;
@@ -123,84 +162,85 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
backdrop-filter: blur(5px);
transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;
color: white;
font-size: 18px;
min-width: 120px;
text-align: left;
font-size: 18px;
}
.hidden {
opacity: 0;
visibility: hidden;
display: none;
pointer-events: none;
}
.info-content {
margin-top: 8px;
}
.player-name {
font-weight: bold;
margin-bottom: 4px;
}
.player-name.ally {
color: #4CAF50;
}
.type-label {
font-size: 14px;
opacity: 0.8;
}
.unit-details {
margin-top: 4px;
}
.health-bar {
height: 4px;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 2px;
margin-top: 4px;
}
.health-fill {
height: 100%;
background-color: #4CAF50;
border-radius: 2px;
transition: width 0.2s ease-out;
}
.exit-button {
background: none;
border: none;
color: white;
font-size: 40px;
cursor: pointer;
padding: 4px;
opacity: 0.7;
transition: opacity 0.2s;
}
.exit-button:hover {
opacity: 1;
}
@media (max-width: 768px) {
.overlay-container {
.container {
top: 5px;
right: 5px;
}
.controls {
width: 30px;
}
.player-info {
padding: 6px 10px;
font-size: 12px;
min-width: 100px;
}
.exit-button {
width: 30px;
height: 30px;
font-size: 16px;
.exit-button {
width: 30px;
height: 30px;
font-size: 16px;
}
.type-label {
font-size: 12px;
}
}
`;
private renderPlayerInfo(player: Player) {
return html`
<div class="info-content">
<div class="name ${player.isAlly ? 'ally' : 'enemy'}">${player.name}</div>
<div class="type-label">Player Territory</div>
</div>
`;
}
private renderUnitInfo(unit: Unit) {
return html`
<div class="info-content">
<div class="name ${unit.isAlly ? 'ally' : 'enemy'}">${unit.owner}</div>
<div class="unit-details">
<div class="type-label">${unit.type}</div>
<div class="health-bar">
<div class="health-fill" style="width: ${unit.health}%"></div>
</div>
</div>
</div>
`;
}
render() {
return html`
<div class="overlay-container">
<div class="controls">
<button class="exit-button" @click=${this.onExitButtonClick}>×</button>
</div>
<div class="info-panel ${this._infoType === 'none' ? 'hidden' : ''}">
${this._infoType === 'player' && this._playerInfo
? this.renderPlayerInfo(this._playerInfo)
: this._infoType === 'unit' && this._unitInfo
? this.renderUnitInfo(this._unitInfo)
: nothing}
</div>
</div>
`;
}
}
+1 -4
View File
@@ -1,13 +1,9 @@
import { GameEnv, Theme } from "../../../core/configuration/Config";
import { EventBus } from "../../../core/EventBus";
import { WinEvent } from "../../../core/execution/WinCheckExecution";
import { AllianceRequest, AllianceRequestReplyEvent, Game, Player } from "../../../core/game/Game";
import { ClientID } from "../../../core/Schemas";
import { ContextMenuEvent } from "../../InputHandler";
import { Layer } from "./Layer";
import { TransformHandler } from "../TransformHandler";
import { MessageType } from "./EventsDisplay";
import { SendBreakAllianceIntentEvent } from "../../Transport";
import { consolex } from "../../../core/Consolex";
interface MenuOption {
@@ -151,6 +147,7 @@ export class UILayer implements Layer {
button.onmouseout = () => button.style.backgroundColor = '#4A90E2';
}
onWinEvent(event: WinEvent) {
consolex.log(`${event.winner.name()} won the game!!}`)
this.showWinModal(event.winner)
+1 -1
View File
@@ -8,7 +8,7 @@ export const devConfig = new class extends DefaultConfig {
unitInfo(type: UnitType): UnitInfo {
const info = super.unitInfo(type)
const oldCost = info.cost
info.cost = (p: Player) => oldCost(p) / 20
info.cost = (p: Player) => oldCost(p) / 10000
return info
}