From c619129b3f8083c1b0e73f001f0a35f5e0263629 Mon Sep 17 00:00:00 2001 From: Restart2008 Date: Thu, 20 Nov 2025 23:11:14 -0800 Subject: [PATCH] Revert "feat: Update ExclamationMarkIcon.svg for WatchOut ping" This reverts commit c05b99fdb6336391873a000795338681feb0f309. --- resources/images/ExclamationMarkIcon.svg | 5 - src/client/graphics/GameRenderer.ts | 21 ++-- src/client/graphics/fx/PingFx.ts | 112 ---------------------- src/client/graphics/layers/FxLayer.ts | 17 +--- src/core/game/Ping.ts | 17 ---- tests/client/graphics/ProgressBar.test.ts | 28 +----- tests/client/graphics/UILayer.test.ts | 25 ----- 7 files changed, 12 insertions(+), 213 deletions(-) delete mode 100644 resources/images/ExclamationMarkIcon.svg delete mode 100644 src/client/graphics/fx/PingFx.ts delete mode 100644 src/core/game/Ping.ts diff --git a/resources/images/ExclamationMarkIcon.svg b/resources/images/ExclamationMarkIcon.svg deleted file mode 100644 index 8c417fc73..000000000 --- a/resources/images/ExclamationMarkIcon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index 2ccccb39a..1410cdbbd 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -24,7 +24,6 @@ import { MainRadialMenu } from "./layers/MainRadialMenu"; import { MultiTabModal } from "./layers/MultiTabModal"; import { NameLayer } from "./layers/NameLayer"; import { NukeTrajectoryPreviewLayer } from "./layers/NukeTrajectoryPreviewLayer"; -import { PingTrajectoryPreviewLayer } from "./layers/PingTrajectoryPreviewLayer"; import { PerformanceOverlay } from "./layers/PerformanceOverlay"; import { PlayerInfoOverlay } from "./layers/PlayerInfoOverlay"; import { PlayerPanel } from "./layers/PlayerPanel"; @@ -205,13 +204,13 @@ export function createRenderer( headsUpMessage.game = game; const structureLayer = new StructureLayer(game, eventBus, transformHandler); - const samRadiusLayer = new SAMRadiusLayer( - game, - eventBus, - transformHandler, - uiState, - ); - const pingTrajectoryPreviewLayer = new PingTrajectoryPreviewLayer(game, eventBus, transformHandler); + const samRadiusLayer = new SAMRadiusLayer( + game, + eventBus, + transformHandler, + uiState, + ); + const performanceOverlay = document.querySelector( "performance-overlay", ) as PerformanceOverlay; @@ -244,10 +243,9 @@ export function createRenderer( structureLayer, samRadiusLayer, new UnitLayer(game, eventBus, transformHandler), - new FxLayer(game, eventBus), + new FxLayer(game), new UILayer(game, eventBus, transformHandler), new NukeTrajectoryPreviewLayer(game, eventBus, transformHandler), - pingTrajectoryPreviewLayer, new StructureIconsLayer(game, eventBus, uiState, transformHandler), new NameLayer(game, transformHandler, eventBus), eventsDisplay, @@ -294,7 +292,6 @@ export function createRenderer( export class GameRenderer { private context: CanvasRenderingContext2D; - private inputHandler: InputHandler; constructor( private game: GameView, @@ -308,11 +305,9 @@ export class GameRenderer { const context = canvas.getContext("2d"); if (context === null) throw new Error("2d context not supported"); this.context = context; - this.inputHandler = new InputHandler(uiState, canvas, eventBus, transformHandler); } initialize() { - this.inputHandler.initialize(); this.eventBus.on(RedrawGraphicsEvent, () => this.redraw()); this.layers.forEach((l) => l.init?.()); diff --git a/src/client/graphics/fx/PingFx.ts b/src/client/graphics/fx/PingFx.ts deleted file mode 100644 index 872632046..000000000 --- a/src/client/graphics/fx/PingFx.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { GameView } from "../../../core/game/GameView"; -import { PingType } from "../../../core/game/Ping"; -import { TileRef } from "../../../core/game/GameMap"; -import { Fx } from "./Fx"; - - -export class PingFx implements Fx { - private readonly durationMs: number = 3000; // Ping visible for 3 seconds - private startTime: number; - private readonly pingColor: string; - private get icon(): HTMLImageElement | null { - return PingFx.iconCache.get(this.pingType) || null; - } - - - - constructor( - private game: GameView, - private pingType: PingType, - private tile: TileRef, - ) { - this.startTime = performance.now(); - this.pingColor = this.getPingColor(pingType); - // Trigger preload but don't store the result - const iconPath = this.getIconPath(pingType); - if (iconPath) { - PingFx.preloadIcon(pingType, iconPath); - } - } - - private getPingColor(pingType: PingType): string { - switch (pingType) { - case PingType.Attack: - return "rgba(255, 0, 0, 0.7)"; // Red - case PingType.Retreat: - return "rgba(0, 255, 0, 0.7)"; // Green - case PingType.Defend: - return "rgba(0, 0, 255, 0.7)"; // Blue - case PingType.WatchOut: - return "rgba(255, 255, 0, 0.7)"; // Yellow - default: - return "rgba(128, 128, 128, 0.7)"; // Default to gray - } - } - - private getIconPath(pingType: PingType): string | null { - switch (pingType) { - case PingType.Attack: - return "/resources/images/SwordIconWhite.svg"; - case PingType.Retreat: - return "/resources/images/BackIconWhite.svg"; - case PingType.Defend: - return "/resources/images/ShieldIconWhite.svg"; - case PingType.WatchOut: - return "/resources/images/QuestionMarkIcon.svg"; - default: - return null; - } - } -private static iconCache = new Map(); - private static preloadIcon(pingType: PingType, iconPath: string): void { - if (!PingFx.iconCache.has(pingType)) { - const img = new Image(); - img.onload = () => { - PingFx.iconCache.set(pingType, img); - }; - img.onerror = () => { - console.error(`Failed to load ping icon: ${iconPath}`); - PingFx.iconCache.set(pingType, null); // Mark as failed - }; - img.src = iconPath; - } - } - - renderTick(duration: number, context: CanvasRenderingContext2D): boolean { - const elapsed = performance.now() - this.startTime; - if (elapsed > this.durationMs) { - return false; // Fx is finished - } - - const x = this.game.x(this.tile); - const y = this.game.y(this.tile); - - // Calculate offset to center coordinates (same as canvas drawing) - const offsetX = -this.game.width() / 2; - const offsetY = -this.game.height() / 2; - - context.save(); - context.globalAlpha = 1 - elapsed / this.durationMs; // Fade out effect - - // Draw colored circle - context.fillStyle = this.pingColor; - context.beginPath(); - context.arc(x + offsetX, y + offsetY, 15, 0, 2 * Math.PI); - context.fill(); - - // Draw icon - if (this.icon && this.icon.complete) { - const iconSize = 20; - context.drawImage( - this.icon, - x + offsetX - iconSize / 2, - y + offsetY - iconSize / 2, - iconSize, - iconSize, - ); - } - - context.restore(); - return true; // Fx is still active - } -} diff --git a/src/client/graphics/layers/FxLayer.ts b/src/client/graphics/layers/FxLayer.ts index f243590a7..e1c454e5c 100644 --- a/src/client/graphics/layers/FxLayer.ts +++ b/src/client/graphics/layers/FxLayer.ts @@ -18,11 +18,6 @@ import { SpriteFx } from "../fx/SpriteFx"; import { TargetFx } from "../fx/TargetFx"; import { TextFx } from "../fx/TextFx"; import { UnitExplosionFx } from "../fx/UnitExplosionFx"; -import { PingPlacedEvent, PingType } from "../../../core/game/Ping"; -import { PingFx } from "../fx/PingFx"; -import { EventBus } from "../../../core/EventBus"; -import { PingPlacedEvent, PingType } from "../../../core/game/Ping"; -import { PingFx } from "../fx/PingFx"; import { Layer } from "./Layer"; export class FxLayer implements Layer { private canvas: HTMLCanvasElement; @@ -38,7 +33,7 @@ export class FxLayer implements Layer { private boatTargetFxByUnitId: Map = new Map(); private nukeTargetFxByUnitId: Map = new Map(); - constructor(private game: GameView, private eventBus: EventBus) { + constructor(private game: GameView) { this.theme = this.game.config().theme(); } @@ -358,16 +353,6 @@ export class FxLayer implements Layer { } catch (err) { console.error("Failed to load FX sprites:", err); } - - this.eventBus.on(PingPlacedEvent, (event) => { - const pingFx = new PingFx( - this.game, - this.animatedSpriteLoader, - event.type, - event.tile, - ); - this.allFx.push(pingFx); - }); } redraw(): void { diff --git a/src/core/game/Ping.ts b/src/core/game/Ping.ts deleted file mode 100644 index 81e3d4147..000000000 --- a/src/core/game/Ping.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TileRef } from "./GameMap"; - -export enum PingType { - Attack, - Retreat, - Defend, - WatchOut, -} - -export class Ping { - constructor( - public type: PingType, - public tile: TileRef, - ) {} -} - -export class PingPlacedEvent extends Ping {} diff --git a/tests/client/graphics/ProgressBar.test.ts b/tests/client/graphics/ProgressBar.test.ts index 11a86a14c..50189a9e3 100644 --- a/tests/client/graphics/ProgressBar.test.ts +++ b/tests/client/graphics/ProgressBar.test.ts @@ -11,39 +11,17 @@ describe("ProgressBar", () => { canvas = document.createElement("canvas"); canvas.width = 100; canvas.height = 20; - ctx = { - clearRect: jest.fn(), - fillRect: jest.fn(), - beginPath: jest.fn(), - arc: jest.fn(), - fill: jest.fn(), - stroke: jest.fn(), - measureText: jest.fn(() => ({ width: 10 })), - fillText: jest.fn(), - save: jest.fn(), - restore: jest.fn(), - translate: jest.fn(), - rotate: jest.fn(), - drawImage: jest.fn(), - setTransform: jest.fn(), - globalAlpha: 1, - fillStyle: "", - strokeStyle: "", - lineWidth: 1, - font: "", - } as unknown as CanvasRenderingContext2D; - jest - .spyOn(HTMLCanvasElement.prototype, "getContext") - .mockReturnValue(ctx); + ctx = canvas.getContext("2d")!; }); it("should initialize and draw the background", () => { const spyClearRect = jest.spyOn(ctx, "clearRect"); const spyFillRect = jest.spyOn(ctx, "fillRect"); + const spyFillStyle = jest.spyOn(ctx, "fillStyle", "set"); const bar = new ProgressBar(["#ff0000", "#00ff00"], ctx, 2, 2, 80, 10, 0.5); expect(spyClearRect).toHaveBeenCalledWith(0, 0, 82, 12); expect(spyFillRect).toHaveBeenCalledWith(1, 1, 80, 10); - expect(ctx.fillStyle).toBe("#00ff00"); + expect(spyFillStyle).toHaveBeenCalledWith("#00ff00"); expect(bar.getX()).toBe(2); expect(bar.getY()).toBe(2); }); diff --git a/tests/client/graphics/UILayer.test.ts b/tests/client/graphics/UILayer.test.ts index e40fc57c2..c899ca079 100644 --- a/tests/client/graphics/UILayer.test.ts +++ b/tests/client/graphics/UILayer.test.ts @@ -30,31 +30,6 @@ describe("UILayer", () => { }; eventBus = { on: jest.fn() }; transformHandler = {}; - - // Mock the HTMLCanvasElement.prototype.getContext method - jest - .spyOn(HTMLCanvasElement.prototype, "getContext") - .mockReturnValue({ - clearRect: jest.fn(), - fillRect: jest.fn(), - beginPath: jest.fn(), - arc: jest.fn(), - fill: jest.fn(), - stroke: jest.fn(), - measureText: jest.fn(() => ({ width: 10 })), - fillText: jest.fn(), - save: jest.fn(), - restore: jest.fn(), - translate: jest.fn(), - rotate: jest.fn(), - drawImage: jest.fn(), - setTransform: jest.fn(), - globalAlpha: 1, - fillStyle: "", - strokeStyle: "", - lineWidth: 1, - font: "", - } as unknown as CanvasRenderingContext2D); }); it("should initialize and redraw canvas", () => {