Zombies: organic approach, honest eaten radius; restore CPU strength
- Personal lane offset (homeOff ±0.8m) + a per-zombie shamble wobble so on your half they fan around you instead of stacking into one column. - Eaten check weights depth by 0.75 (z is foreshortened in the projection), so a head-on shambler kills you when it LOOKS on top of you — fixes "they touch me and I don't die." Lateral reach unchanged. - Revert aiFlub 0.14 -> 0.09 (undo the CPU weakening). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
eacad1ffca
commit
148da4713c
2 files changed
+9
-6
No files matched your search
@@ -14,7 +14,7 @@ export const TUNE = {
|
||||
serveSpeed: 21, serveQualitySpeed: 7,
|
||||
aimError: 2.4, // m of scatter at quality 0
|
||||
perfectMs: 45, // |offset from window center| for PERFECT
|
||||
aiQualityMin: 0.45, aiQualityMax: 0.85, aiFlub: 0.14, // ~86% of returns land (was 0.09) — a touch easier to beat
|
||||
aiQualityMin: 0.45, aiQualityMax: 0.85, aiFlub: 0.09,
|
||||
aiReaction: 0.45, // s before the CPU reads your shot — well-aimed corners are winners
|
||||
autoAssist: matchMedia('(pointer: coarse)').matches ? 1.15 : 0, // auto-run speed factor (mobile)
|
||||
zSpeed: 0.7, // zombie shamble speed m/s
|
||||
|
||||
+8
-5
@@ -19,7 +19,8 @@ let spawnT = 1.5, moanT = 3;
|
||||
|
||||
export function spawnZombie(x, z, variant) {
|
||||
const ramp = 1 + Math.min(1.5, G.splatT / 70); // they get faster the longer you survive
|
||||
const zb = { x, z, v: TUNE.zSpeed * ramp * (0.8 + Math.random() * 0.4), walkT: Math.random() * 9, variant };
|
||||
const zb = { x, z, v: TUNE.zSpeed * ramp * (0.8 + Math.random() * 0.4), walkT: Math.random() * 9,
|
||||
homeOff: (Math.random() * 2 - 1) * 0.8, variant }; // personal lane offset so they don't stack into a column
|
||||
if (variant === 'f') { zb.v = Math.min(TUNE.runnerVMax, zb.v * TUNE.runnerSpeed); shriek(); } // shriek = the fairness contract; capped so late runners stay reactable
|
||||
if (variant === 'g') { zb.v *= 0.55; zb.hp = TUNE.bruteHp; } // slow, but soaks hits
|
||||
if (variant === 's') zb.shieldT = 0; // chair up; > 0 = seconds of stagger left
|
||||
@@ -184,11 +185,13 @@ export function updateZombies(dt) {
|
||||
zb.z += zb.v * dt;
|
||||
if (zb.shieldT > 0) zb.shieldT -= dt; // staggered chair comes back up when this runs out
|
||||
if (zb.variant === 'r') { /* the racket boss holds station — its AI owns its x */ }
|
||||
else if (G.mode === 'splatter' && zb.z > COURT.netZ) // on YOUR half they home in on you
|
||||
zb.x += Math.sign(P.x - zb.x) * Math.min(Math.abs(P.x - zb.x), zb.v * 0.7 * dt);
|
||||
else
|
||||
else if (G.mode === 'splatter' && zb.z > COURT.netZ) { // on YOUR half they close in — each on its own lane, not a column
|
||||
const tx = P.x + zb.homeOff;
|
||||
zb.x += Math.sign(tx - zb.x) * Math.min(Math.abs(tx - zb.x), zb.v * 0.7 * dt)
|
||||
+ Math.sin(zb.walkT * 2.3) * 0.25 * dt; // shamble wobble — the approach reads organic, not tracked
|
||||
} else
|
||||
zb.x += Math.sin(zb.walkT * 1.7) * 0.15 * dt; // far half: aimless shamble
|
||||
if (G.mode === 'splatter' && Math.hypot(zb.x - P.x, zb.z - P.z) < TUNE.eatenR + (zb.variant === 'g' ? 0.2 : 0)) { // it got you — touch is HONEST now: sprite overlap = eaten
|
||||
if (G.mode === 'splatter' && Math.hypot(zb.x - P.x, (zb.z - P.z) * 0.75) < TUNE.eatenR + (zb.variant === 'g' ? 0.2 : 0)) { // z weighted down: depth is foreshortened, so a head-on shambler eats you when it LOOKS on top of you
|
||||
gore.push({ x: P.x, z: P.z, r: 0.9, a: 0.9 });
|
||||
for (let k = 0; k < 30; k++) parts.push({
|
||||
x: P.x, y: 1.1, z: P.z,
|
||||
|
||||
Reference in new issue
Block a user