diff --git a/src/mobile-hud.js b/src/mobile-hud.js index 649d477..c804f77 100644 --- a/src/mobile-hud.js +++ b/src/mobile-hud.js @@ -1,5 +1,5 @@ import topHudSrc from './assets/controller/top-hud.js'; -import playerHealthFrameSrc from './assets/controller/player-health-hq-frame.js'; +import playerHealthSrc from './assets/controller/player-health.js'; import enemyHealthSrc from './assets/controller/enemy-health.js'; import cannonRoundelSrc from './assets/controller/cannon-roundel.js'; import helmFrameSrc from './assets/controller/helm-frame.js'; @@ -88,23 +88,7 @@ if (!isDesktopPointer.matches) { .steam-player-card { left: 1%; - background-size: 100% 100%; - } - - .steam-player-health-fill { - position: absolute; - left: 41.2%; - top: 60.2%; - width: 45.4%; - height: 16.4%; - border-radius: 999px; - transform: scaleX(1); - transform-origin: left center; - background: linear-gradient(180deg, #62ff39 0%, #10d326 100%); - box-shadow: inset 0 1px 2px rgba(255,255,255,.6), 0 0 4px rgba(68,255,68,.28); - transition: transform 150ms ease-out, background 120ms linear; - pointer-events: none; - z-index: 1; + background-size: 400% 300%; } .steam-player-card.steam-hit { @@ -581,8 +565,7 @@ if (!isDesktopPointer.matches) { return piece; }; - const playerHealthPiece = addHealthPiece('steam-player-card', playerHealthFrameSrc, ` - + const playerHealthPiece = addHealthPiece('steam-player-card', playerHealthSrc, ` SPARROW 100/100 `); @@ -675,17 +658,6 @@ if (!isDesktopPointer.matches) { piece.style.backgroundPosition = `${(col / 3) * 100}% ${(row / 2) * 100}%`; }; - const setPlayerHealthLevel = (current, max) => { - const pct = max > 0 ? clamp01(current / max) : 0; - const fill = fields['player-health-fill']; - fill.style.transform = `scaleX(${pct})`; - fill.style.background = pct > 0.66 - ? 'linear-gradient(180deg, #62ff39 0%, #10d326 100%)' - : pct > 0.33 - ? 'linear-gradient(180deg, #fff23f 0%, #e6c20d 100%)' - : 'linear-gradient(180deg, #ff6b2f 0%, #e72418 100%)'; - }; - const updateRadar = (contacts = []) => { radarDots.forEach((dot, index) => { const contact = contacts[index]; @@ -735,7 +707,10 @@ if (!isDesktopPointer.matches) { fields['enemy-name'].textContent = target?.name || 'PIRATE'; fields['enemy-hull'].textContent = target ? `${Math.max(0, target.hull || 0)}/${Math.max(1, target.maxHull || 120)}` : 'CLEAR'; - setPlayerHealthLevel(playerHull, playerMaxHull); + setHealthFrame( + playerHealthPiece, + healthFrame(playerHull, playerMaxHull), + ); setHealthFrame( enemyHealthPiece, target ? healthFrame(target.hull || 0, target.maxHull || 120) : 11, diff --git a/tests/wiring.test.mjs b/tests/wiring.test.mjs index fb1d15f..394485e 100644 --- a/tests/wiring.test.mjs +++ b/tests/wiring.test.mjs @@ -125,18 +125,16 @@ test('portrait health sprites sit tightly beneath the top HUD', async () => { assert.match(source, /@media \(min-width: 700px\)[\s\S]*?\.steam-player-card,[\s\S]*?\.steam-enemy-card \{[\s\S]*?top: clamp\(70px, 20vh, 104px\)/); }); -test('mobile HUD uses a high-resolution player frame with continuous health fill', async () => { +test('mobile HUD uses the player sprite sheet for health states', async () => { const source = await read('src/mobile-hud.js'); - assert.match(source, /import playerHealthFrameSrc from '.\/assets\/controller\/player-health-hq-frame\.js'/); + assert.match(source, /import playerHealthSrc from '.\/assets\/controller\/player-health\.js'/); assert.match(source, /import enemyHealthSrc from '.\/assets\/controller\/enemy-health\.js'/); - assert.match(source, /addHealthPiece\('steam-player-card', playerHealthFrameSrc/); - assert.match(source, /data-steam="player-health-fill"/); - assert.match(source, /const setPlayerHealthLevel = \(current, max\) =>/); - assert.match(source, /fill\.style\.transform = \`scaleX\(\$\{pct\}\)\`/); - assert.match(source, /setPlayerHealthLevel\(playerHull, playerMaxHull\)/); - assert.match(source, /\.steam-player-health-fill \{[\s\S]*?width: 45\.4%/); - assert.doesNotMatch(source, /playerHealthFullSrc|playerHealthMidSrc|playerHealthLowSrc/); + assert.match(source, /addHealthPiece\('steam-player-card', playerHealthSrc/); + assert.match(source, /\.steam-player-card \{[\s\S]*?background-size: 400% 300%/); + assert.match(source, /setHealthFrame\(\s*playerHealthPiece,\s*healthFrame\(playerHull, playerMaxHull\)/); + assert.doesNotMatch(source, /player-health-hq-frame\.js/); + assert.doesNotMatch(source, /steam-player-health-fill/); }); test('uploaded top HUD uses its new aspect ratio', async () => { @@ -245,12 +243,12 @@ test('player overlap resolves an explicitly tagged pirate projectile before queu }); -test('player health frame stays static while CSS fill tracks exact hull percentage', async () => { +test('player health uses the same 4x3 sprite frame addressing as enemy health', async () => { const source = await read('src/mobile-hud.js'); - assert.match(source, /player-health-hq-frame\.js/); - assert.match(source, /const setPlayerHealthLevel = \(current, max\) =>/); - assert.match(source, /fill\.style\.transform = \`scaleX\(\$\{pct\}\)\`/); - assert.doesNotMatch(source, /setPlayerHealthImage/); - assert.doesNotMatch(source, /player-health-frame-v2-/); + assert.match(source, /const healthFrame = \(current, max\) =>/); + assert.match(source, /const setHealthFrame = \(piece, frame\) =>/); + assert.match(source, /setHealthFrame\(\s*playerHealthPiece,/); + assert.match(source, /background-size: 400% 300%/); + assert.doesNotMatch(source, /setPlayerHealthLevel/); });