Run the player on four frames instead of two
Two frames is a lurch, and he is on screen the whole run — during a horde he is the only thing moving. Regenerated the whole cycle in one pass rather than bolting two new frames onto the old pair, so the four are consistent with each other, then fitted them per channel onto the mean and sd of the frames that stay (idle + swing): mean error under 3 of 255, so he does not change colour when he starts moving. The pick is frame-count driven, not hardcoded — the opponent has no run3/run4 and stays on two, and the cycle RATE is unchanged either way: more frames subdivide the stride, they do not speed it up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No files matched your search
|
After Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -97,6 +97,6 @@
|
||||
<p id="build"></p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="main.js?v=56"></script>
|
||||
<script type="module" src="main.js?v=57"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -155,9 +155,9 @@ export function proj(x, y, z) {
|
||||
|
||||
// ---------------------------------------------------------------- sprites ----
|
||||
// assets/<name>.png; game falls back to code-drawn figures until sprites load.
|
||||
const SPRV = 51; // asset cache-buster — bump with main.js?v=N (see the img.src note below)
|
||||
const SPRV = 52; // 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_swing1','p_swing2',
|
||||
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',
|
||||
'x_ump','x_boyrun1','x_boyrun2','x_boyrun3','x_boyrun4','x_crowd','x_crowd2','x_ads',
|
||||
'x_boymop1','x_boymop2','x_boymop3','x_boymop4', // the push cycle, used only while he is stopped and working
|
||||
@@ -434,7 +434,11 @@ function drawChar(ch) {
|
||||
const rising = Math.sin(w) * Math.cos(w) > 0;
|
||||
name = pre + (rising ? 'bounce2' : 'bounce'); // hand up while the ball rises, pat down exactly at the apex
|
||||
}
|
||||
if (ch.pose === 'run') name = pre + (Math.floor(ch.runT * 9) % 2 ? 'run1' : 'run2');
|
||||
// Four-frame run where the frames exist (the player), two where they don't (the opponent). Same
|
||||
// CYCLE rate either way — more frames subdivide the stride, they do not speed it up, exactly as
|
||||
// ZFRAMES does for the shamblers.
|
||||
const runN = SPR[pre + 'run4'] ? 4 : 2;
|
||||
if (ch.pose === 'run') name = pre + 'run' + (Math.floor(ch.runT * 4.5 * runN) % runN + 1);
|
||||
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 + (G.phase === 'toss' ? 'toss' : 'smash');
|
||||
@@ -442,7 +446,7 @@ function drawChar(ch) {
|
||||
// Auto-fire: the idle sprite carries a racket at his hip AND drawMgRacket puts one in his hands —
|
||||
// two rackets. The run frames are the racket-less art, so he jogs on the spot instead.
|
||||
if (ch.side === 'P' && ch.pose === 'idle' && G.mode === 'splatter' && (G.horde || G.mgT > 0))
|
||||
name = pre + (Math.floor(G.idleT * 6) % 2 ? 'run1' : 'run2');
|
||||
name = pre + 'run' + (Math.floor(G.idleT * 3 * runN) % runN + 1);
|
||||
const img = SPR[name];
|
||||
drawShadow(p.x, p.y, hpx * 0.22, hpx * 0.06);
|
||||
if (img) {
|
||||
|
||||