mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 22:55:22 +00:00
fix: resolve parsing errors in FxLayer and RadialMenuElements
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 257 B |
+17
-19
@@ -1,10 +1,10 @@
|
||||
import { EventBus, GameEvent } from "../core/EventBus";
|
||||
import { UnitType } from "../core/game/Game";
|
||||
import { UnitView } from "../core/game/GameView";
|
||||
import { UserSettings } from "../core/game/UserSettings";
|
||||
import { PingType } from "../core/game/Ping";
|
||||
import { UIState } from "./graphics/UIState";
|
||||
import { UserSettings } from "../core/game/UserSettings";
|
||||
import { TransformHandler } from "./graphics/TransformHandler";
|
||||
import { UIState } from "./graphics/UIState";
|
||||
import { ReplaySpeedMultiplier } from "./utilities/ReplaySpeedMultiplier";
|
||||
|
||||
export class MouseUpEvent implements GameEvent {
|
||||
@@ -501,26 +501,24 @@ export class InputHandler {
|
||||
this.eventBus.emit(new PingSelectedEvent(null));
|
||||
return;
|
||||
}
|
||||
{
|
||||
const localX = event.clientX - rect.left;
|
||||
const localY = event.clientY - rect.top;
|
||||
const worldCoords = this.transformHandler.screenToWorldCoordinates(
|
||||
localX,
|
||||
localY,
|
||||
);
|
||||
this.eventBus.emit(
|
||||
new PingPlacedEvent(
|
||||
this.uiState.currentPingType,
|
||||
worldCoords.x,
|
||||
worldCoords.y,
|
||||
),
|
||||
);
|
||||
}
|
||||
const localX = event.clientX - rect.left;
|
||||
const localY = event.clientY - rect.top;
|
||||
const worldCoords = this.transformHandler.screenToWorldCoordinates(
|
||||
localX,
|
||||
localY,
|
||||
);
|
||||
this.eventBus.emit(
|
||||
new PingPlacedEvent(
|
||||
this.uiState.currentPingType,
|
||||
worldCoords.x,
|
||||
worldCoords.y,
|
||||
),
|
||||
);
|
||||
this.uiState.currentPingType = null;
|
||||
this.eventBus.emit(new PingSelectedEvent(null)); // Clear ping preview
|
||||
this.eventBus.emit(new PingSelectedEvent(null));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (event.pointerType === "touch") {
|
||||
this.eventBus.emit(new TouchEvent(event.x, event.y));
|
||||
event.preventDefault();
|
||||
|
||||
@@ -298,6 +298,10 @@ export function createRenderer(
|
||||
|
||||
export class GameRenderer {
|
||||
private context: CanvasRenderingContext2D;
|
||||
private rafId?: number;
|
||||
private resizeListener?: () => void;
|
||||
private contextLostListener?: () => void;
|
||||
private contextRestoredListener?: () => void;
|
||||
|
||||
constructor(
|
||||
private game: GameView,
|
||||
@@ -316,33 +320,59 @@ export class GameRenderer {
|
||||
private redrawEventCleanup?: () => void;
|
||||
|
||||
initialize() {
|
||||
this.redrawEventCleanup = this.eventBus.on(RedrawGraphicsEvent, () =>
|
||||
this.redrawEventCleanup = this.eventBus.on(RedrawGraphicsEvent, () =>
|
||||
this.redraw(),
|
||||
);
|
||||
this.layers.forEach((l) => l.init?.());
|
||||
|
||||
document.body.appendChild(this.canvas);
|
||||
window.addEventListener("resize", () => this.resizeCanvas());
|
||||
this.resizeListener = () => this.resizeCanvas();
|
||||
window.addEventListener("resize", this.resizeListener);
|
||||
this.resizeCanvas();
|
||||
|
||||
//show whole map on startup
|
||||
this.transformHandler.centerAll(0.9);
|
||||
|
||||
let rafId = requestAnimationFrame(() => this.renderGame());
|
||||
this.canvas.addEventListener("contextlost", () => {
|
||||
cancelAnimationFrame(rafId);
|
||||
});
|
||||
this.canvas.addEventListener("contextrestored", () => {
|
||||
this.contextLostListener = () => {
|
||||
if (this.rafId !== undefined) {
|
||||
cancelAnimationFrame(this.rafId);
|
||||
this.rafId = undefined;
|
||||
}
|
||||
};
|
||||
this.canvas.addEventListener("contextlost", this.contextLostListener);
|
||||
|
||||
this.contextRestoredListener = () => {
|
||||
this.redraw();
|
||||
rafId = requestAnimationFrame(() => this.renderGame());
|
||||
});
|
||||
this.rafId = requestAnimationFrame(() => this.renderGame());
|
||||
};
|
||||
this.canvas.addEventListener(
|
||||
"contextrestored",
|
||||
this.contextRestoredListener,
|
||||
);
|
||||
|
||||
this.rafId = requestAnimationFrame(() => this.renderGame());
|
||||
}
|
||||
|
||||
|
||||
destroy() {
|
||||
this.redrawEventCleanup?.();
|
||||
if (this.rafId !== undefined) {
|
||||
cancelAnimationFrame(this.rafId);
|
||||
}
|
||||
if (this.resizeListener) {
|
||||
window.removeEventListener("resize", this.resizeListener);
|
||||
}
|
||||
if (this.contextLostListener) {
|
||||
this.canvas.removeEventListener("contextlost", this.contextLostListener);
|
||||
}
|
||||
if (this.contextRestoredListener) {
|
||||
this.canvas.removeEventListener(
|
||||
"contextrestored",
|
||||
this.contextRestoredListener,
|
||||
);
|
||||
}
|
||||
this.layers.forEach((l) => l.destroy?.());
|
||||
}
|
||||
|
||||
|
||||
resizeCanvas() {
|
||||
this.canvas.width = window.innerWidth;
|
||||
this.canvas.height = window.innerHeight;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { TileRef } from "../../../core/game/GameMap";
|
||||
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;
|
||||
@@ -12,8 +11,6 @@ export class PingFx implements Fx {
|
||||
return PingFx.iconCache.get(this.pingType) ?? null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
constructor(
|
||||
private game: GameView,
|
||||
private pingType: PingType,
|
||||
@@ -57,9 +54,10 @@ export class PingFx implements Fx {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static iconCache = new Map<PingType, HTMLImageElement | null>();
|
||||
private static iconCache = new Map<PingType, HTMLImageElement | null>();
|
||||
private static preloadIcon(pingType: PingType, iconPath: string): void {
|
||||
if (!PingFx.iconCache.has(pingType)) {
|
||||
PingFx.iconCache.set(pingType, null); // Reserve spot immediately
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
PingFx.iconCache.set(pingType, img);
|
||||
@@ -109,4 +107,4 @@ private static iconCache = new Map<PingType, HTMLImageElement | null>();
|
||||
context.restore();
|
||||
return true; // Fx is still active
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,6 +353,12 @@ export class FxLayer implements Layer {
|
||||
}
|
||||
|
||||
private pingEventCleanup?: () => void;
|
||||
dispose() {
|
||||
if (this.pingEventCleanup) {
|
||||
this.pingEventCleanup();
|
||||
this.pingEventCleanup = undefined;
|
||||
}
|
||||
}
|
||||
async init() {
|
||||
this.redraw();
|
||||
try {
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import {
|
||||
MenuElement,
|
||||
MenuElementParams,
|
||||
COLORS,
|
||||
} from "./RadialMenuElements";
|
||||
import swordIcon from "../../../../resources/images/SwordIconWhite.svg";
|
||||
import retreatIcon from "../../../../resources/images/BackIconWhite.svg";
|
||||
import defendIcon from "../../../../resources/images/ShieldIconWhite.svg";
|
||||
import pingIcon from "../../../../resources/images/PingIcon.svg";
|
||||
import watchOutIcon from "../../../../resources/images/QuestionMarkIcon.svg";
|
||||
import defendIcon from "../../../../resources/images/ShieldIconWhite.svg";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { PingType } from "../../../core/game/Ping";
|
||||
import { PingSelectedEvent } from "../../InputHandler";
|
||||
import { COLORS, MenuElement, MenuElementParams } from "./RadialMenuElements";
|
||||
|
||||
export const PING_ICON = swordIcon;
|
||||
export const PING_ICON = pingIcon;
|
||||
|
||||
export const PING_COLORS = {
|
||||
[PingType.Attack]: "#ff0000",
|
||||
@@ -34,9 +30,10 @@ function createPingElement(
|
||||
color: PING_COLORS[pingType],
|
||||
disabled: () => false,
|
||||
action: (params?: MenuElementParams) => {
|
||||
if (!params) return;
|
||||
eventBus.emit(new PingSelectedEvent(pingType));
|
||||
params.closeMenu();
|
||||
if (params) {
|
||||
params.closeMenu();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -84,4 +81,4 @@ export function createPingMenu(eventBus: EventBus): MenuElement {
|
||||
pingWatchOutElement,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,6 +572,8 @@ export const rootMenuElement: MenuElement = {
|
||||
icon: infoIcon,
|
||||
color: COLORS.info,
|
||||
subMenu: (params: MenuElementParams) => {
|
||||
if (params === undefined) return [];
|
||||
|
||||
let ally = allyRequestElement;
|
||||
if (params.selected?.isAlliedWith(params.myPlayer)) {
|
||||
ally = allyBreakElement;
|
||||
@@ -584,7 +586,7 @@ export const rootMenuElement: MenuElement = {
|
||||
|
||||
const menuItems: (MenuElement | null)[] = [
|
||||
infoMenuElement,
|
||||
createPingMenu(params.eventBus),
|
||||
createPingMenu(params.eventBus),
|
||||
...(isOwnTerritory
|
||||
? [deleteUnitElement, ally, buildMenuElement]
|
||||
: [boatMenuElement, ally, attackMenuElement]),
|
||||
|
||||
+5
-14
@@ -1,17 +1,8 @@
|
||||
import { TileRef } from "./GameMap";
|
||||
|
||||
export enum PingType {
|
||||
Attack,
|
||||
Retreat,
|
||||
Defend,
|
||||
WatchOut,
|
||||
}
|
||||
export type PingType = "attack" | "retreat" | "defend" | "watchOut";
|
||||
|
||||
export class Ping {
|
||||
constructor(
|
||||
public type: PingType,
|
||||
public tile: TileRef,
|
||||
) {}
|
||||
}
|
||||
|
||||
export class PingPlacedEvent extends Ping {}
|
||||
export type Ping = {
|
||||
type: PingType;
|
||||
tile: TileRef;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user