Use joystick sprite sheet for helm control

This commit is contained in:
Admin 2026-09-17 23:11:32 +00:00
parent 7de41ab9ba
commit c4bf5cfcef

View File

@ -2,7 +2,6 @@ import Phaser from 'phaser';
import topHudSrc from './assets/controller/top-hud.js'; import topHudSrc from './assets/controller/top-hud.js';
import leftStatusSrc from './assets/controller/left-status.js'; import leftStatusSrc from './assets/controller/left-status.js';
import rightControlsSrc from './assets/controller/right-controls.js'; import rightControlsSrc from './assets/controller/right-controls.js';
import radarPanelSrc from './assets/controller/radar-panel.js';
import cannonActionSrc from './assets/controller/cannon-action.js'; import cannonActionSrc from './assets/controller/cannon-action.js';
import helmActionSrc from './assets/controller/helm-action.js'; import helmActionSrc from './assets/controller/helm-action.js';
@ -159,6 +158,29 @@ if (!isDesktopPointer.matches) {
left: 1%; left: 1%;
bottom: clamp(88px, 11.5vh, 106px); bottom: clamp(88px, 11.5vh, 106px);
width: min(39vw, 174px); width: min(39vw, 174px);
aspect-ratio: 1;
}
.steam-helm-sprite {
position: absolute;
inset: 0;
background-repeat: no-repeat;
background-size: 300% 300%;
background-position: 50% 50%;
pointer-events: none;
}
.steam-helm-label {
position: absolute;
left: 50%;
bottom: 5%;
transform: translateX(-50%);
width: 55%;
text-align: center;
color: #ffe5a0;
font-size: clamp(8px, 2.5vw, 12px);
letter-spacing: .12em;
pointer-events: none;
} }
#steam-radar-contacts { #steam-radar-contacts {
@ -193,12 +215,6 @@ if (!isDesktopPointer.matches) {
background: currentColor; background: currentColor;
} }
.steam-helm-wrap {
left: -1%;
bottom: max(2px, env(safe-area-inset-bottom));
width: 48%;
}
.steam-cannon-port, .steam-cannon-port,
.steam-cannon-starboard { .steam-cannon-starboard {
right: -1%; right: -1%;
@ -266,14 +282,14 @@ if (!isDesktopPointer.matches) {
} }
#mobile-controls.controller-active #drag-stick { #mobile-controls.controller-active #drag-stick {
left: 0; left: 1%;
bottom: max(2px, env(safe-area-inset-bottom)); bottom: clamp(88px, 11.5vh, 106px);
top: auto; top: auto;
width: 48%; width: min(39vw, 174px);
height: auto; height: auto;
aspect-ratio: 378 / 192; aspect-ratio: 1;
border: 0; border: 0;
border-radius: 34%; border-radius: 50%;
background: transparent; background: transparent;
box-shadow: none; box-shadow: none;
backdrop-filter: none; backdrop-filter: none;
@ -349,9 +365,9 @@ if (!isDesktopPointer.matches) {
bottom: 78px; bottom: 78px;
} }
.steam-helm-wrap,
#mobile-controls.controller-active #drag-stick { #mobile-controls.controller-active #drag-stick {
width: 43%; width: 34vw;
bottom: 78px;
} }
.steam-cannon-port, .steam-cannon-port,
@ -406,16 +422,21 @@ if (!isDesktopPointer.matches) {
<span class="steam-card-value" data-steam="enemy-hull">CLEAR</span> <span class="steam-card-value" data-steam="enemy-hull">CLEAR</span>
`); `);
const radarPiece = addPiece('steam-radar-wrap', radarPanelSrc, ` const radarPiece = document.createElement('div');
radarPiece.className = 'steam-piece steam-radar-wrap';
const helmSprite = document.createElement('div');
helmSprite.className = 'steam-helm-sprite';
helmSprite.style.backgroundImage = `url("${helmActionSrc}")`;
radarPiece.appendChild(helmSprite);
radarPiece.insertAdjacentHTML('beforeend', `
<div id="steam-radar-contacts"> <div id="steam-radar-contacts">
<span class="steam-radar-player"></span> <span class="steam-radar-player"></span>
</div> </div>
<span class="steam-helm-label">HELM</span>
`); `);
hud.appendChild(radarPiece);
addPiece('steam-helm-wrap', helmActionSrc, `
<span class="steam-action-label">HELM</span>
<span class="steam-action-sub">DRAG TO STEER</span>
`);
addPiece('steam-cannon-port', cannonActionSrc, ` addPiece('steam-cannon-port', cannonActionSrc, `
<span class="steam-action-label">PORT FIRE</span> <span class="steam-action-label">PORT FIRE</span>
@ -437,6 +458,40 @@ if (!isDesktopPointer.matches) {
); );
const radarContacts = radarPiece.querySelector('#steam-radar-contacts'); const radarContacts = radarPiece.querySelector('#steam-radar-contacts');
const stick = document.querySelector('#drag-stick');
const setHelmFrame = (x, y) => {
const column = x < -0.22 ? 0 : x > 0.22 ? 2 : 1;
const row = y < -0.22 ? 0 : y > 0.22 ? 2 : 1;
helmSprite.style.backgroundPosition = `${column * 50}% ${row * 50}%`;
};
let helmPointer = null;
const updateHelmFrame = (event) => {
if (!stick) return;
const rect = stick.getBoundingClientRect();
const x = (event.clientX - (rect.left + rect.width / 2)) / (rect.width / 2);
const y = (event.clientY - (rect.top + rect.height / 2)) / (rect.height / 2);
setHelmFrame(x, y);
};
stick?.addEventListener('pointerdown', (event) => {
helmPointer = event.pointerId;
updateHelmFrame(event);
});
stick?.addEventListener('pointermove', (event) => {
if (event.pointerId === helmPointer) updateHelmFrame(event);
});
const resetHelmFrame = (event) => {
if (helmPointer !== null && event?.pointerId !== undefined && event.pointerId !== helmPointer) return;
helmPointer = null;
setHelmFrame(0, 0);
};
stick?.addEventListener('pointerup', resetHelmFrame);
stick?.addEventListener('pointercancel', resetHelmFrame);
stick?.addEventListener('lostpointercapture', resetHelmFrame);
const radarDots = Array.from({ length: 10 }, () => { const radarDots = Array.from({ length: 10 }, () => {
const dot = document.createElement('span'); const dot = document.createElement('span');
dot.className = 'steam-radar-dot'; dot.className = 'steam-radar-dot';