add # troops to UI

This commit is contained in:
evanpelle
2024-09-03 19:13:42 -07:00
parent cac66c2186
commit 1f590d0f4a
7 changed files with 121 additions and 87 deletions
+8 -9
View File
@@ -83,24 +83,23 @@
* BUG: attacks starts slow but gets faster DONE 9/2/2024
* BUG: can't join game if click with 1s before start DONE 9/2/2024
* boat not going around world dist vs distwrapped DONE 9/2/2024
* test & deploy game
* test & deploy game DONE 9/2/2024
--- v2 Release
* put number of troops ui DONE 9/3/2024
* boats leave trails
* names don't appear when zoomed out
* don't join game for reason
* make names bigger
* send boat even if touching
* put number of troops ui
* boats leave trails
* directed expansion
* more random names for game id & client id
* Make fake humans
* directed expansion
* win condition & popup
* BUG: tiles get left behind during conquer; still problem?
* UI: win condition & popup
* UI: boats
* UI: current attacks
* UI: leader board
* Load terrain dataImage in background
* BUG: shore tiles left behind during conquer
* BUG: when sending boat to TerraNullius, only takes one tile
* REFACTOR: give terranullius an ID, game.player() returns terranullius
* REFACTOR: ocean is considered TerraNullius ?
+1 -1
View File
@@ -16,7 +16,7 @@ export function createClientGame(name: string, clientID: ClientID, ip: string |
let eventBus = new EventBus()
let game = createGame(terrainMap, eventBus, config)
let terrainRenderer = new TerrainRenderer(game)
let gameRenderer = new GameRenderer(game, terrainRenderer)
let gameRenderer = new GameRenderer(game, clientID, terrainRenderer)
return new ClientGame(
name,
+9 -62
View File
@@ -5,6 +5,9 @@ import {DragEvent, ZoomEvent} from "../InputHandler";
import {NameRenderer} from "./NameRenderer";
import {TerrainRenderer} from "./TerrainRenderer";
import {TerritoryRenderer} from "./TerritoryRenderer";
import {ClientID} from "../../core/Schemas";
import {renderTroops} from "./Utils";
import {UIRenderer} from "./UIRenderer";
export class GameRenderer {
private territoryCanvas: HTMLCanvasElement
@@ -20,16 +23,16 @@ export class GameRenderer {
private nameRenderer: NameRenderer;
private territoryRenderer: TerritoryRenderer;
private uiRenderer: UIRenderer;
private theme: Theme
private exitButton: HTMLButtonElement;
constructor(private gs: Game, private terrainRenderer: TerrainRenderer) {
constructor(private gs: Game, private clientID: ClientID, private terrainRenderer: TerrainRenderer) {
this.theme = gs.config().theme()
this.nameRenderer = new NameRenderer(gs, this.theme)
this.territoryRenderer = new TerritoryRenderer(gs)
this.uiRenderer = new UIRenderer(gs, this.theme, clientID)
}
initialize() {
@@ -46,6 +49,7 @@ export class GameRenderer {
this.nameRenderer.initialize()
this.terrainRenderer.init()
this.territoryRenderer.init()
this.uiRenderer.init()
document.body.appendChild(this.canvas);
@@ -59,53 +63,9 @@ export class GameRenderer {
this.territoryContext = this.territoryCanvas.getContext('2d')
this.territoryContext.globalAlpha = 0.4;
this.createExitButton()
requestAnimationFrame(() => this.renderGame());
}
createExitButton() {
this.exitButton = document.createElement('button');
this.exitButton.innerHTML = '✕'; // HTML entity for "×" (multiplication sign)
this.exitButton.style.position = 'fixed';
this.exitButton.style.top = '20px';
this.exitButton.style.right = '20px';
this.exitButton.style.zIndex = '1000';
this.exitButton.style.width = '40px';
this.exitButton.style.height = '40px';
this.exitButton.style.fontSize = '20px';
this.exitButton.style.fontWeight = 'bold';
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.4)'; // More translucent red
this.exitButton.style.color = 'white';
this.exitButton.style.border = 'none';
this.exitButton.style.borderRadius = '50%';
this.exitButton.style.cursor = 'pointer';
this.exitButton.style.display = 'flex';
this.exitButton.style.justifyContent = 'center';
this.exitButton.style.alignItems = 'center';
this.exitButton.style.transition = 'background-color 0.3s';
this.exitButton.addEventListener('mouseover', () => {
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; // Less translucent on hover
});
this.exitButton.addEventListener('mouseout', () => {
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.3)'; // Back to more translucent
});
this.exitButton.addEventListener('click', () => this.onExitButtonClick());
document.body.appendChild(this.exitButton);
}
onExitButtonClick() {
console.log('Button clicked!');
window.location.reload();
// Add your button action here
}
resizeCanvas() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
@@ -147,11 +107,13 @@ export class GameRenderer {
this.context.restore()
this.renderUIBar()
this.uiRenderer.render(this.context)
requestAnimationFrame(() => this.renderGame());
}
// TODO: move to UIRenderer
renderUIBar() {
if (!this.gs.inSpawnPhase()) {
return
@@ -191,21 +153,6 @@ export class GameRenderer {
this.canvas.height = Math.ceil(height / window.devicePixelRatio);
}
// paintTerritory(tile: Tile) {
// this.clearCell(tile.cell())
// // if (!tile.hasOwner()) {
// // this.clearCell(tile.cell())
// // return
// // }
// // this.territoryContext.clearRect(tile.cell().x, tile.cell().y, 1, 1);
// if (tile.isBorder()) {
// this.territoryContext.fillStyle = this.theme.borderColor(tile.owner().id()).toRgbString()
// } else {
// this.territoryContext.fillStyle = this.theme.territoryColor(tile.owner().id()).alpha(100).toHex()
// }
// this.territoryContext.fillRect(tile.cell().x, tile.cell().y, 1, 1);
// }
paintCell(cell: Cell, color: Colord) {
color = color.alpha(10) // Assign the result back to color
this.territoryContext.fillStyle = color.toHslString()
+3 -14
View File
@@ -3,6 +3,7 @@ import {PseudoRandom} from "../../core/PseudoRandom"
import {calculateBoundingBox} from "../../core/Util"
import {Theme} from "../../core/configuration/Config"
import {placeName} from "./NameBoxCalculator"
import {renderTroops} from "./Utils"
class RenderInfo {
public isVisible = true
@@ -123,19 +124,7 @@ export class NameRenderer {
context.fillText(render.player.name(), nameCenterX, nameCenterY - render.fontSize / 2);
context.font = `bold ${render.fontSize}px ${this.theme.font()}`;
let troopsStr: string = ""
let troops = render.player.troops() / 10
if (troops > 100000) {
troopsStr = String(Math.floor(troops / 1000)) + "K"
} else if (troops > 10000) {
troopsStr = String((troops / 1000).toFixed(1)) + "K"
} else if (troops > 1000) {
troopsStr = String((troops / 1000).toFixed(2)) + "K"
}
else {
troopsStr = String(Math.floor(troops))
}
context.fillText(troopsStr, nameCenterX, nameCenterY + render.fontSize);
context.fillText(renderTroops(render.player.troops()), nameCenterX, nameCenterY + render.fontSize);
}
}
+73
View File
@@ -0,0 +1,73 @@
import {Theme} from "../../core/configuration/Config";
import {Game} from "../../core/Game";
import {ClientID} from "../../core/Schemas";
import {renderTroops} from "./Utils";
export class UIRenderer {
private exitButton: HTMLButtonElement;
constructor(private game: Game, private theme: Theme, private clientID: ClientID) {
}
init() {
this.createExitButton()
}
createExitButton() {
this.exitButton = document.createElement('button');
this.exitButton.innerHTML = '✕'; // HTML entity for "×" (multiplication sign)
this.exitButton.style.position = 'fixed';
this.exitButton.style.top = '20px';
this.exitButton.style.right = '20px';
this.exitButton.style.zIndex = '1000';
this.exitButton.style.width = '40px';
this.exitButton.style.height = '40px';
this.exitButton.style.fontSize = '20px';
this.exitButton.style.fontWeight = 'bold';
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.4)'; // More translucent red
this.exitButton.style.color = 'white';
this.exitButton.style.border = 'none';
this.exitButton.style.borderRadius = '50%';
this.exitButton.style.cursor = 'pointer';
this.exitButton.style.display = 'flex';
this.exitButton.style.justifyContent = 'center';
this.exitButton.style.alignItems = 'center';
this.exitButton.style.transition = 'background-color 0.3s';
this.exitButton.addEventListener('mouseover', () => {
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; // Less translucent on hover
});
this.exitButton.addEventListener('mouseout', () => {
this.exitButton.style.backgroundColor = 'rgba(255, 0, 0, 0.3)'; // Back to more translucent
});
this.exitButton.addEventListener('click', () => this.onExitButtonClick());
document.body.appendChild(this.exitButton);
}
render(context) {
const p = this.game.players().find(p => p.clientID() == this.clientID);
let troopCount = p ? `${renderTroops(p.troops())}` : '';
context.save();
context.fillStyle = 'black';
context.textAlign = 'center';
context.textBaseline = 'top';
const x = 65 + 18 * (troopCount.length - 2); // Right edge of the text area
const y = 40; // Distance from the top
context.font = `bold ${60}px ${this.theme.font()}`;
context.fillText(troopCount, x, y);
context.restore();
}
onExitButtonClick() {
console.log('Button clicked!');
window.location.reload();
// Add your button action here
}
}
+17
View File
@@ -0,0 +1,17 @@
export function renderTroops(troops: number): string {
let troopsStr = ''
troops = troops / 10
if (troops > 100000) {
troopsStr = String(Math.floor(troops / 1000)) + "K"
} else if (troops > 10000) {
troopsStr = String((troops / 1000).toFixed(1)) + "K"
} else if (troops > 1000) {
troopsStr = String((troops / 1000).toFixed(2)) + "K"
}
else {
troopsStr = String(Math.floor(troops))
}
return troopsStr
}
+10 -1
View File
@@ -1,4 +1,4 @@
import {PlayerInfo} from "../Game";
import {Player, PlayerInfo} from "../Game";
import {DefaultConfig} from "./DefaultConfig";
export const devConfig = new class extends DefaultConfig {
@@ -25,4 +25,13 @@ export const devConfig = new class extends DefaultConfig {
}
return 5000
}
troopAdditionRate(player: Player): number {
let max = Math.sqrt(player.numTilesOwned()) * 2000 + 10000 + 10000
max = Math.min(max, 1_000_000)
let toAdd = 10 + (player.troops() + Math.sqrt(player.troops() * player.numTilesOwned())) / 200 * 100
return Math.min(player.troops() + toAdd, max)
}
}