sounds
This commit is contained in:
parent
c6ba3e38a2
commit
37087d08a7
189 changed files with 12864 additions and 9589 deletions
80
js/ants.js
80
js/ants.js
|
|
@ -3,15 +3,15 @@
|
|||
const ANT_NEST_START_COUNT = 6;
|
||||
const ANT_NEST_MAX_COUNT = 10;
|
||||
const ANT_NEST_MAX_OUTSIDE = 3;
|
||||
const ANT_WORKER_HP = 32;
|
||||
const ANT_QUEEN_HP = 180;
|
||||
const ANT_WORKER_HP = 48;
|
||||
const ANT_QUEEN_HP = 270;
|
||||
const ANT_WORKER_RADIUS = 4.2;
|
||||
const ANT_QUEEN_RADIUS = 9.5;
|
||||
const ANT_WORKER_SEARCH_SPEED = 8.625;
|
||||
const ANT_WORKER_RETURN_SPEED = 12.0;
|
||||
const ANT_WORKER_RETURN_WEAK_SPEED = 6.0;
|
||||
const ANT_WORKER_DRAG_SPEED = 4.125;
|
||||
const ANT_QUEEN_SPEED = 9.0;
|
||||
const ANT_WORKER_SEARCH_SPEED = 12.9375;
|
||||
const ANT_WORKER_RETURN_SPEED = 18.0;
|
||||
const ANT_WORKER_RETURN_WEAK_SPEED = 9.0;
|
||||
const ANT_WORKER_DRAG_SPEED = 6.1875;
|
||||
const ANT_QUEEN_SPEED = 13.5;
|
||||
|
||||
function clampAntHp(v) {
|
||||
return clamp(Number(v) || 0, 0, ANT_WORKER_HP);
|
||||
|
|
@ -43,6 +43,11 @@ function syncAntNestCount(worldRef, nest) {
|
|||
ensureAntNestWorkerPool(nest);
|
||||
const outside = (worldRef?.ants || []).filter(a => a && !a.dead && a.kind === "worker" && a.homeId === nest.id).length;
|
||||
nest.antCount = clamp((nest.antWorkers?.length || 0) + outside, 0, ANT_NEST_MAX_COUNT);
|
||||
if (nest.antCount <= 0) {
|
||||
nest.antWorkers = [];
|
||||
nest.amount = 0;
|
||||
if (worldRef) worldRef.drawListDirty = true;
|
||||
}
|
||||
return nest.antCount;
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +86,50 @@ class AntActor {
|
|||
return (this.world?.items || []).find(it => it && !it.dead && it.id === this.homeId && it.type === "ant_nest") || null;
|
||||
}
|
||||
|
||||
adoptableNest() {
|
||||
let best = null;
|
||||
let bestScore = Infinity;
|
||||
for (const nest of this.world?.items || []) {
|
||||
if (!nest || nest.dead || nest.type !== "ant_nest") continue;
|
||||
if (typeof ensureAntNestWorkerPool === "function") ensureAntNestWorkerPool(nest);
|
||||
const outside = (this.world?.ants || []).filter(a => a && !a.dead && a.kind === "worker" && a.homeId === nest.id).length;
|
||||
const inside = Array.isArray(nest.antWorkers) ? nest.antWorkers.length : Math.max(0, (nest.antCount || 0) - outside);
|
||||
const count = inside + outside;
|
||||
if (count >= (ANT_NEST_MAX_COUNT || 10)) continue;
|
||||
const d = distXY(this.x, this.y, nest.x, nest.y);
|
||||
const score = d + count * 26;
|
||||
if (score < bestScore) { best = nest; bestScore = score; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
updateWanderNoNest(dt) {
|
||||
const adopt = this.adoptableNest();
|
||||
if (adopt) {
|
||||
this.homeId = adopt.id;
|
||||
this.state = "return";
|
||||
this.targetId = "";
|
||||
this.targetToken = 0;
|
||||
this.targetRef = null;
|
||||
this.world.drawListDirty = true;
|
||||
return;
|
||||
}
|
||||
this.targetId = "";
|
||||
this.targetToken = 0;
|
||||
this.targetRef = null;
|
||||
this.state = "wander";
|
||||
this.nextTurn -= dt;
|
||||
if (this.nextTurn <= 0) {
|
||||
this.wanderAngle += rand(-1.35, 1.35);
|
||||
this.nextTurn = rand(0.55, 1.45);
|
||||
}
|
||||
const speed = (ANT_WORKER_SEARCH_SPEED || 10) * clamp((this.hp || this.maxHp || ANT_WORKER_HP) / Math.max(1, this.maxHp || ANT_WORKER_HP), 0.45, 1.0) * 0.86;
|
||||
this.vx = Math.cos(this.wanderAngle) * speed;
|
||||
this.vy = Math.sin(this.wanderAngle) * speed * 0.78;
|
||||
this.x = clamp(this.x + this.vx * dt, CONFIG.worldPadding, this.world.w - CONFIG.worldPadding);
|
||||
this.y = clamp(this.y + this.vy * dt, CONFIG.worldPadding, this.world.h - CONFIG.worldPadding);
|
||||
}
|
||||
|
||||
targetTarinai() {
|
||||
if (this.targetRef && !this.targetRef.dead && this.targetRef.id === this.targetId && this.targetRef.liveToken === this.targetToken) return this.targetRef;
|
||||
const live = this.world?.liveTarinaiById?.(this.targetId, this.targetToken) || null;
|
||||
|
|
@ -134,7 +183,7 @@ class AntActor {
|
|||
updateWorker(dt) {
|
||||
const home = this.homeNest();
|
||||
if (!home) {
|
||||
this.dead = true;
|
||||
this.updateWanderNoNest(dt);
|
||||
return;
|
||||
}
|
||||
if (this.hp <= 0) {
|
||||
|
|
@ -158,6 +207,7 @@ class AntActor {
|
|||
target.antDraggedBy = this.id;
|
||||
target.fearTimer = Math.max(target.fearTimer || 0, 0.55);
|
||||
target.thought = "\u30a2\u30ea\u306b\u904b\u3070\u308c\u3066\u3044\u308b";
|
||||
audio.antDrag?.();
|
||||
this.world.drawListDirty = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -180,7 +230,9 @@ class AntActor {
|
|||
|
||||
returnToNest(home) {
|
||||
if (!home || home.dead || home.type !== "ant_nest") {
|
||||
this.dead = true;
|
||||
const adopt = this.adoptableNest();
|
||||
if (adopt) { this.homeId = adopt.id; this.state = "return"; return; }
|
||||
this.updateWanderNoNest(0.016);
|
||||
return;
|
||||
}
|
||||
ensureAntNestWorkerPool(home).push(clampAntHp(this.hp));
|
||||
|
|
@ -262,6 +314,7 @@ class AntActor {
|
|||
dieAsCorpse(home = null) {
|
||||
if (this.dead) return;
|
||||
this.dead = true;
|
||||
audio.antDie?.();
|
||||
const corpse = new Item("ant_corpse", this.x, this.y);
|
||||
corpse.amount = 24;
|
||||
corpse.workerSprite = this.workerSpriteId();
|
||||
|
|
@ -288,9 +341,12 @@ class AntActor {
|
|||
base.antCount = ANT_NEST_START_COUNT;
|
||||
base.antWorkers = buildAntWorkerPool(ANT_NEST_START_COUNT);
|
||||
if (!force && this.world.placementBlocked?.(base)) return null;
|
||||
audio.antNest?.();
|
||||
this.world.items.push(base);
|
||||
this.world.itemCounts[base.type] = (this.world.itemCounts[base.type] || 0) + 1;
|
||||
this.world.rebuildSpatial?.();
|
||||
this.world.markTerrainDirty?.("ant-nest-built");
|
||||
this.world.emit?.("ant:nest-built", { nest: base, queen: this });
|
||||
this.world.rebuildSpatial?.(true);
|
||||
this.world.drawListDirty = true;
|
||||
this.world.log("\u5973\u738b\u30a2\u30ea\u304c\u65b0\u3057\u3044\u30a2\u30ea\u306e\u5de3\u3092\u4f5c\u3063\u305f\u3002", "event");
|
||||
return base;
|
||||
|
|
@ -347,7 +403,7 @@ class AntActor {
|
|||
const img = typeof getRenderableImage === "function" ? getRenderableImage(id, id) : images.get(id);
|
||||
const lightState = lighting || getLightingState(this.world);
|
||||
ctx.save();
|
||||
const shadow = projectedShadowParams(lightState, this.kind === "queen" ? 0.58 : 0.26);
|
||||
const shadow = projectedShadowParams(lightState, this.kind === "queen" ? 0.78 : 0.26);
|
||||
drawProjectedShadow(ctx, this.x, this.y + this.r * 0.62, this.r * 1.5, this.r * 0.30, { ...shadow, alpha: shadow.alpha * 0.72 });
|
||||
ctx.translate(this.x, this.y);
|
||||
const angle = this.kind === "queen"
|
||||
|
|
@ -355,7 +411,7 @@ class AntActor {
|
|||
: Math.atan2(this.vy || 0, this.vx || 1);
|
||||
ctx.rotate(angle);
|
||||
if (img) {
|
||||
const w = this.kind === "queen" ? this.r * 4.1 : this.r * 3.8;
|
||||
const w = this.kind === "queen" ? this.r * 5.25 : this.r * 3.8;
|
||||
const metrics = getImageMetrics(id);
|
||||
const h = w * (metrics?.ratio || 0.52);
|
||||
ctx.globalAlpha = 0.96;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue