diff --git a/assets/_sheet_cpu34.png b/assets/_sheet_cpu34.png new file mode 100644 index 0000000..27277de Binary files /dev/null and b/assets/_sheet_cpu34.png differ diff --git a/assets/_sheet_shield34.png b/assets/_sheet_shield34.png new file mode 100644 index 0000000..36c6ee9 Binary files /dev/null and b/assets/_sheet_shield34.png differ diff --git a/assets/z_c2.png b/assets/z_c2.png index e8ef971..7a26b51 100644 Binary files a/assets/z_c2.png and b/assets/z_c2.png differ diff --git a/assets/z_c3.png b/assets/z_c3.png new file mode 100644 index 0000000..aae9a40 Binary files /dev/null and b/assets/z_c3.png differ diff --git a/assets/z_c4.png b/assets/z_c4.png new file mode 100644 index 0000000..77b54cd Binary files /dev/null and b/assets/z_c4.png differ diff --git a/assets/z_s3.png b/assets/z_s3.png index 4863327..c4387a2 100644 Binary files a/assets/z_s3.png and b/assets/z_s3.png differ diff --git a/assets/z_s4.png b/assets/z_s4.png new file mode 100644 index 0000000..fa79dfd Binary files /dev/null and b/assets/z_s4.png differ diff --git a/assets/z_sdown.png b/assets/z_sdown.png new file mode 100644 index 0000000..4863327 Binary files /dev/null and b/assets/z_sdown.png differ diff --git a/index.html b/index.html index 2ee4c9e..1f1bd19 100644 --- a/index.html +++ b/index.html @@ -97,6 +97,6 @@

- + diff --git a/render.js b/render.js index 34d3540..de3cf74 100644 --- a/render.js +++ b/render.js @@ -155,7 +155,7 @@ export function proj(x, y, z) { // ---------------------------------------------------------------- sprites ---- // assets/.png; game falls back to code-drawn figures until sprites load. -const SPRV = 56; // asset cache-buster — bump with main.js?v=N (see the img.src note below) +const SPRV = 57; // asset cache-buster — bump with main.js?v=N (see the img.src note below) const SPR = {}; for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','p_run1','p_run2','p_run3','p_run4','p_swing1','p_swing2', 'o_idle1','o_idle2','o_bounce','o_bounce2','o_toss','o_smash','o_run1','o_run2','o_swing1','o_swing2', @@ -171,7 +171,9 @@ for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash',' 'z_a1','z_a2','z_a3','z_a4','z_b1','z_b2','z_b3','z_b4','z_c1','z_c2', 'z_d1','z_d2','z_d3','z_d4', // the steward: bigger body, hi-vis vest, 4-frame walk 'z_awb','z_bwb','z_cw1b','z_cw2b','z_dw','z_dwb', // ...and every wound skin's second frame: wounded bodies walk too - 'z_f1','z_f2','z_f3','z_f4','z_g1','z_g2','z_g3','z_g4','z_gw','z_s1','z_s2','z_s3', + 'z_f1','z_f2','z_f3','z_f4','z_g1','z_g2','z_g3','z_g4','z_gw', + 'z_s1','z_s2','z_s3','z_s4','z_sdown', // the chair spectator: 4-frame shuffle + the staggered pose + 'z_c3','z_c4', // ...and the turned CPU walks on four frames too 'z_cw1','z_cw2','z_aw','z_bw', // wounded skins for multi-hit enemies (racket boss, brute, and now the classic shamblers) 'w_ball','w_bomb','w_triple','w_fire','w_gun', // weapon-rack icons 'scoreboard']) { @@ -264,7 +266,7 @@ function drawBoy(b) { // for 'z_g-1' — a sprite that does not exist, and drawStatic silently draws nothing. That is the // blinking Oliver saw on the way in, on exactly the bodies that step off distance: brutes and bosses. const stepFrame = (v, n) => ((Math.floor(v) % n) + n) % n; // 0..n-1, whatever the sign of v -const ZFRAMES = { a: 4, b: 4, f: 4, d: 4, g: 4 }; // 4-frame walk cycles where sheets exist; the rest stay 2 +const ZFRAMES = { a: 4, b: 4, f: 4, d: 4, g: 4, s: 4, c: 4 }; // 4-frame walk cycles where sheets exist; the rest stay 2 // The rogue ball machine, on its own generated sheet: a dented hopper cart on wheels with a barrel // aimed down-court, and a second frame with the muzzle flashing. Oliver called the first, procedural // version "naively painted" — it was four rects, which is fine for fire but not for furniture the @@ -303,13 +305,15 @@ function drawZombie(zb) { // WALKED, like its wound lurch below, // or the feet slide (same cycle length) : Math.floor(zb.walkT * (zb.variant === 'f' ? 6 : 2.6) * N / 2) % N + 1; - if (zb.variant === 's' && zb.shieldT > 0) frame = 3; // chair dropped — hit it NOW + const chairDown = zb.variant === 's' && zb.shieldT > 0; // chair dropped — hit it NOW. Its own sprite + // now (z_sdown); it used to be walk frame 3, + // which a 4-frame cycle would walk right through let h = zb.variant === 'g' ? 2.7 : zb.variant === 'd' ? 2.15 : rk ? 1.85 : 1.8; // the brute towers half again over the crowd; the steward stands between him and it if (zb.variant === 'B') h = 1.8 * (zb.scale || 1.5); // ...and a chapter boss towers over the brute // wounded skins: multi-hit enemies show their damage as hp drops (arm off → head gone, still // shambling). The blood is NOT painted in — open wounds gush live particles (see bleed() in // zombies.js). Fall back to the healthy sprite until the wounded PNG has loaded. - let name = 'z_' + v + frame; + let name = chairDown && SPR.z_sdown ? 'z_sdown' : 'z_' + v + frame; if (zb.variant === 'g' && zb.hp < TUNE.bruteHp) { // one arm → both → head gone → ribs out const stage = ['z_gw4', 'z_gw3', 'z_gw2', 'z_gw'][Math.max(0, Math.min(3, zb.hp - 1))]; if (SPR[stage]) {