mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-01 19:03:25 +00:00
Revert "feat: Update ExclamationMarkIcon.svg for WatchOut ping"
This reverts commit c05b99fdb6.
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<polygon points="50,10 90,90 10,90" fill="none" stroke="white" stroke-width="5"/>
|
||||
<circle cx="50" cy="75" r="5" fill="white"/>
|
||||
<rect x="47" y="30" width="6" height="35" fill="white"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 260 B |
@@ -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?.());
|
||||
|
||||
|
||||
@@ -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<PingType, HTMLImageElement | null>();
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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<number, TargetFx> = new Map();
|
||||
private nukeTargetFxByUnitId: Map<number, NukeAreaFx> = 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 {
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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", () => {
|
||||
|
||||
Reference in New Issue
Block a user