animation, gathering, deposit, ui

This commit is contained in:
Vasyl Kazakov
2026-06-02 18:22:20 +03:00
parent 6363396f84
commit e14b97b5e7
61 changed files with 2379 additions and 539 deletions
+83
View File
@@ -0,0 +1,83 @@
import { Color, Material, Mesh, Object3D, Vector3 } from "three";
import { ResourceScreenFly } from "../Resources/ResourceScreenFly";
import {
findInteractiveZoneFromMap,
getInteractiveZoneCenter,
INTERACTIVE_ZONE_NAME,
} from "./MapInteractiveZone";
const FILL_TARGET = 10;
const FILL_COLOR = new Color(0x2db83a);
export class InteractiveZoneC {
private static zoneRoot: Object3D | null = null;
private static deposited = 0;
private static baseColors = new WeakMap<Material, Color>();
static init(mapObject: Object3D) {
const zone = findInteractiveZoneFromMap(mapObject);
if (!zone) {
console.warn(`Interactive zone not found: ${INTERACTIVE_ZONE_NAME}`);
return;
}
this.zoneRoot = zone;
this.setupMaterials(zone);
}
static getWorldCenter(out = new Vector3()) {
if (!this.zoneRoot) return out.set(0, 0, 0);
return getInteractiveZoneCenter(this.zoneRoot, out);
}
static getScreenCenter() {
return ResourceScreenFly.worldToScreen(this.getWorldCenter());
}
static addDeposit(amount = 1) {
this.deposited += amount;
this.refreshFillVisual();
}
static getFillRatio() {
return Math.min(this.deposited / FILL_TARGET, 1);
}
private static setupMaterials(zone: Object3D) {
zone.traverse((child) => {
if (!(child as Mesh).isMesh) return;
const mesh = child as Mesh;
const sourceMaterial = mesh.material;
if (Array.isArray(sourceMaterial)) return;
if (!sourceMaterial) return;
const cloned = sourceMaterial.clone();
if ("color" in cloned) {
this.baseColors.set(cloned, (cloned.color as Color).clone());
}
mesh.material = cloned;
});
this.refreshFillVisual();
}
private static refreshFillVisual() {
if (!this.zoneRoot) return;
const ratio = this.getFillRatio();
this.zoneRoot.traverse((child) => {
if (!(child as Mesh).isMesh) return;
const material = (child as Mesh).material;
if (Array.isArray(material) || !material) return;
const baseColor = this.baseColors.get(material);
if (!baseColor || !("color" in material)) return;
(material.color as Color).copy(baseColor).lerp(FILL_COLOR, ratio);
});
}
}