some changes
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import { Vector3 } from "three";
|
||||
import { CameraC_internal, UpdateController } from "@hitplay/playable_template";
|
||||
import { ThreeC } from "./ThreeC";
|
||||
import { resourceCounterBgSrc } from "../resources/images/images";
|
||||
import { projectScreenPointToWorldRay } from "../utils/screenWorldProjection";
|
||||
|
||||
// See HudC's identical constant — same reasoning, this is a second instance
|
||||
// of the same anchor technique for a second counter.
|
||||
const ANCHOR_DISTANCE = 2.5;
|
||||
|
||||
// Second resource counter, stacked directly below HudC's own wood counter
|
||||
// (see .resource-hud--pistol in ui.css). The zombie-part chunks dropped by
|
||||
// kills (see ZombiePartC, spent on the pistol's own progression — see
|
||||
// PistolLevelC / its Pay Zone) get the exact same fly-to-a-HUD-counter
|
||||
// treatment wood does, just their own plate and their own live balance.
|
||||
//
|
||||
// Reuses HudC's plate art rather than shipping a second bespoke asset — a
|
||||
// CSS hue-rotate on the plate (see ui.css) is what reads it as a different
|
||||
// currency.
|
||||
export class PistolResourceHudC {
|
||||
private static initialized = false;
|
||||
private static plateEl: HTMLElement;
|
||||
private static countTextEl: HTMLElement;
|
||||
private static lastDisplayedCount = -1;
|
||||
private static balanceGetter: (() => number) | null = null;
|
||||
|
||||
static init() {
|
||||
if (this.initialized) return;
|
||||
this.initialized = true;
|
||||
|
||||
this.buildDom();
|
||||
|
||||
UpdateController.Instance.onUpdate.addDelegate(() => this.update());
|
||||
}
|
||||
|
||||
// Same technique as HudC.getWorldAnchorPosition — see its own comment.
|
||||
static getWorldAnchorPosition(): Vector3 {
|
||||
const canvasRect = ThreeC.renderer.domElement.getBoundingClientRect();
|
||||
const plateRect = this.plateEl.getBoundingClientRect();
|
||||
|
||||
const screenX = plateRect.right;
|
||||
const screenY = plateRect.top + plateRect.height / 2;
|
||||
|
||||
const camera = CameraC_internal.getCamera();
|
||||
const { origin, direction } = projectScreenPointToWorldRay(camera, canvasRect, screenX, screenY);
|
||||
return origin.addScaledVector(direction, ANCHOR_DISTANCE);
|
||||
}
|
||||
|
||||
// Injected rather than importing ZombiePartC/PayZoneC directly, matching
|
||||
// HudC.setBalanceGetter.
|
||||
static setBalanceGetter(getBalance: () => number) {
|
||||
this.balanceGetter = getBalance;
|
||||
}
|
||||
|
||||
private static buildDom() {
|
||||
const holder = document.createElement("div");
|
||||
holder.className = "resource-hud resource-hud--pistol";
|
||||
|
||||
const plate = document.createElement("div");
|
||||
plate.className = "resource-hud__plate";
|
||||
plate.style.backgroundImage = `url(${resourceCounterBgSrc})`;
|
||||
|
||||
const count = document.createElement("span");
|
||||
count.className = "resource-hud__count";
|
||||
|
||||
const countText = document.createElement("span");
|
||||
countText.className = "gamefont-x";
|
||||
countText.textContent = "0";
|
||||
count.appendChild(countText);
|
||||
|
||||
plate.appendChild(count);
|
||||
holder.appendChild(plate);
|
||||
|
||||
const uiRoot = document.getElementById("ui-safe-area") ?? document.body;
|
||||
uiRoot.appendChild(holder);
|
||||
|
||||
this.plateEl = plate;
|
||||
this.countTextEl = countText;
|
||||
}
|
||||
|
||||
private static update() {
|
||||
if (!this.balanceGetter) return;
|
||||
const count = this.balanceGetter();
|
||||
if (count === this.lastDisplayedCount) return;
|
||||
this.lastDisplayedCount = count;
|
||||
this.countTextEl.textContent = String(count);
|
||||
|
||||
this.plateEl.classList.remove("is-bumping");
|
||||
void this.plateEl.offsetWidth;
|
||||
this.plateEl.classList.add("is-bumping");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user