diff --git a/assets/_sheet_opp2.png b/assets/_sheet_opp2.png new file mode 100644 index 0000000..6430f75 Binary files /dev/null and b/assets/_sheet_opp2.png differ diff --git a/assets/_sheet_player2.png b/assets/_sheet_player2.png new file mode 100644 index 0000000..fafd212 Binary files /dev/null and b/assets/_sheet_player2.png differ diff --git a/assets/o_bounce.png b/assets/o_bounce.png new file mode 100644 index 0000000..b111aba Binary files /dev/null and b/assets/o_bounce.png differ diff --git a/assets/o_idle.png b/assets/o_idle.png deleted file mode 100644 index ff30479..0000000 Binary files a/assets/o_idle.png and /dev/null differ diff --git a/assets/o_idle1.png b/assets/o_idle1.png new file mode 100644 index 0000000..a809e1f Binary files /dev/null and b/assets/o_idle1.png differ diff --git a/assets/o_idle2.png b/assets/o_idle2.png new file mode 100644 index 0000000..788d00e Binary files /dev/null and b/assets/o_idle2.png differ diff --git a/assets/o_serve.png b/assets/o_serve.png deleted file mode 100644 index e9d723d..0000000 Binary files a/assets/o_serve.png and /dev/null differ diff --git a/assets/o_smash.png b/assets/o_smash.png new file mode 100644 index 0000000..aa44f43 Binary files /dev/null and b/assets/o_smash.png differ diff --git a/assets/o_toss.png b/assets/o_toss.png new file mode 100644 index 0000000..c89b074 Binary files /dev/null and b/assets/o_toss.png differ diff --git a/assets/p_bounce.png b/assets/p_bounce.png new file mode 100644 index 0000000..2b1579f Binary files /dev/null and b/assets/p_bounce.png differ diff --git a/assets/p_idle.png b/assets/p_idle.png deleted file mode 100644 index a543620..0000000 Binary files a/assets/p_idle.png and /dev/null differ diff --git a/assets/p_idle1.png b/assets/p_idle1.png new file mode 100644 index 0000000..9145939 Binary files /dev/null and b/assets/p_idle1.png differ diff --git a/assets/p_idle2.png b/assets/p_idle2.png new file mode 100644 index 0000000..d9b466b Binary files /dev/null and b/assets/p_idle2.png differ diff --git a/assets/p_serve.png b/assets/p_serve.png deleted file mode 100644 index ecad35d..0000000 Binary files a/assets/p_serve.png and /dev/null differ diff --git a/assets/p_smash.png b/assets/p_smash.png new file mode 100644 index 0000000..45e3498 Binary files /dev/null and b/assets/p_smash.png differ diff --git a/assets/p_toss.png b/assets/p_toss.png new file mode 100644 index 0000000..34d4fdd Binary files /dev/null and b/assets/p_toss.png differ diff --git a/game.js b/game.js index d4c8b35..d0b64e9 100644 --- a/game.js +++ b/game.js @@ -18,7 +18,7 @@ const TUNE = { aimError: 2.4, // m of scatter at quality 0 perfectMs: 45, // |offset from window center| for PERFECT aiQualityMin: 0.55, aiQualityMax: 0.95, aiFlub: 0.05, - autoAssist: matchMedia('(pointer: coarse)').matches ? 0.65 : 0, // auto-run toward ball x (mobile) + autoAssist: matchMedia('(pointer: coarse)').matches ? 1.0 : 0, // auto-run toward the ball (mobile) }; const COURT = { L: 23.77, W: 8.23, netZ: 11.885, netH: 0.914, netW: 10.06, serviceD: 6.4 }; @@ -162,8 +162,8 @@ function say(text, delay = 0) { // ponytail: speechSynthesis umpire; swap for re // ---------------------------------------------------------------- sprites ---- // assets/.png; game falls back to code-drawn figures until sprites load. const SPR = {}; -for (const n of ['p_idle','p_run1','p_run2','p_swing1','p_swing2','p_serve', - 'o_idle','o_run1','o_run2','o_swing1','o_swing2','o_serve']) { +for (const n of ['p_idle1','p_idle2','p_bounce','p_toss','p_smash','p_run1','p_run2','p_swing1','p_swing2', + 'o_idle1','o_idle2','o_bounce','o_toss','o_smash','o_run1','o_run2','o_swing1','o_swing2']) { const img = new Image(); img.onload = () => SPR[n] = img; img.src = 'assets/' + n + '.png'; @@ -396,15 +396,24 @@ function update(dt) { if (phase === 'rally') { P.x += mx * TUNE.playerSpeed * slow * dt; P.z += mz * TUNE.playerSpeed * slow * dt; + let assist = 0; if (!mx && !mz && TUNE.autoAssist > 0 && ball.active && ball.lastHit === 'O') { - const d = ball.x - P.x; // drift toward the incoming ball so one thumb suffices - P.x += Math.sign(d) * Math.min(Math.abs(d), TUNE.playerSpeed * TUNE.autoAssist * slow * dt); + const rate = TUNE.playerSpeed * TUNE.autoAssist * slow * dt; + const dx = ball.x - P.x; // run toward the incoming ball so one thumb suffices + assist = Math.sign(dx) * Math.min(Math.abs(dx), rate); + P.x += assist; + if (ball.bounces > 0) { // ball on our side: also close the depth gap + const dz = Math.max(COURT.netZ + 1.5, Math.min(24.5, ball.z)) - P.z; + P.z += Math.sign(dz) * Math.min(Math.abs(dz), rate); + if (!assist) assist = dz; + } } P.x = Math.max(-6.5, Math.min(6.5, P.x)); P.z = Math.max(COURT.netZ + 1.2, Math.min(26, P.z)); - P.runT += (Math.abs(mx) + Math.abs(mz)) * dt; - if (P.pose !== 'swing' && P.pose !== 'serve') P.pose = (mx || mz) ? 'run' : 'idle'; - if (mx) P.facing = mx > 0 ? 1 : -1; + const moving = mx || mz || Math.abs(assist) > 0.005; + P.runT += moving ? dt : 0; + if (P.pose !== 'swing' && P.pose !== 'serve') P.pose = moving ? 'run' : 'idle'; + if (mx || assist) P.facing = (mx || assist) > 0 ? 1 : -1; } } if (P.swingT >= 0) { P.swingT += dt; trySwing(P, false); if (P.swingT > 0.4) P.swingT = -1; } @@ -492,11 +501,13 @@ function drawChar(ch) { const hpx = 1.88 * p.s; // pick sprite const pre = ch.side === 'P' ? 'p_' : 'o_'; - let name = pre + 'idle'; + let name = pre + (Math.floor(idleT * 1.6) % 2 ? 'idle1' : 'idle2'); // idle weight shift + if (phase === 'pretoss' && ch.side === score.server && ch.pose === 'idle') + name = pre + (Math.abs(Math.sin(idleT * 3.6)) < 0.5 ? 'bounce' : 'idle1'); // crouch as the ball drops if (ch.pose === 'run') name = pre + (Math.floor(ch.runT * 9) % 2 ? 'run1' : 'run2'); if (receiverWaiting) name = pre + (sway > 0 ? 'run1' : 'run2'); // split-step shuffle if (ch.pose === 'swing') name = pre + (ch.poseT < 0.15 ? 'swing1' : 'swing2'); - if (ch.pose === 'serve') name = pre + 'serve'; + if (ch.pose === 'serve') name = pre + (phase === 'toss' ? 'toss' : 'smash'); if (ch.pose === 'run') p.y -= Math.floor(ch.runT * 18) % 2; // 1px run bob const img = SPR[name]; // shadow