Sync helm sprite sheet to steering keys
This commit is contained in:
parent
61c945d7a6
commit
a8fe774382
@ -3,7 +3,7 @@ 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 cannonRoundelSrc from './assets/controller/cannon-roundel.js';
|
import cannonRoundelSrc from './assets/controller/cannon-roundel.js';
|
||||||
import helmActionSrc from './assets/controller/helm-action.js';
|
import helmSpriteSheetSrc from './assets/controller/helm-action.js';
|
||||||
|
|
||||||
const isDesktopPointer = window.matchMedia('(hover: hover) and (pointer: fine)');
|
const isDesktopPointer = window.matchMedia('(hover: hover) and (pointer: fine)');
|
||||||
|
|
||||||
@ -433,7 +433,7 @@ if (!isDesktopPointer.matches) {
|
|||||||
|
|
||||||
const helmSprite = document.createElement('div');
|
const helmSprite = document.createElement('div');
|
||||||
helmSprite.className = 'steam-helm-sprite';
|
helmSprite.className = 'steam-helm-sprite';
|
||||||
helmSprite.style.backgroundImage = `url("${helmActionSrc}")`;
|
helmSprite.style.backgroundImage = `url("${helmSpriteSheetSrc}")`;
|
||||||
radarPiece.appendChild(helmSprite);
|
radarPiece.appendChild(helmSprite);
|
||||||
|
|
||||||
radarPiece.insertAdjacentHTML('beforeend', `
|
radarPiece.insertAdjacentHTML('beforeend', `
|
||||||
@ -462,11 +462,12 @@ if (!isDesktopPointer.matches) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const radarContacts = radarPiece.querySelector('#steam-radar-contacts');
|
const radarContacts = radarPiece.querySelector('#steam-radar-contacts');
|
||||||
const stick = document.querySelector('#drag-stick');
|
|
||||||
|
|
||||||
|
// Drive the 3×3 helm sheet from the same arrow-key state emitted by the
|
||||||
|
// mobile drag control. This keeps the visual frame exactly in sync with
|
||||||
|
// movement and avoids a second, jitter-prone pointer-direction calculation.
|
||||||
|
const helmKeys = new Set();
|
||||||
let helmFrame = '1:1';
|
let helmFrame = '1:1';
|
||||||
let pendingHelmFrame = null;
|
|
||||||
let helmFrameTimer = null;
|
|
||||||
|
|
||||||
const applyHelmFrame = (column, row) => {
|
const applyHelmFrame = (column, row) => {
|
||||||
const key = `${column}:${row}`;
|
const key = `${column}:${row}`;
|
||||||
@ -475,80 +476,35 @@ if (!isDesktopPointer.matches) {
|
|||||||
helmSprite.style.backgroundPosition = `${column * 50}% ${row * 50}%`;
|
helmSprite.style.backgroundPosition = `${column * 50}% ${row * 50}%`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resolveHelmFrame = (x, y) => {
|
const updateHelmFromKeys = () => {
|
||||||
const magnitude = Math.hypot(x, y);
|
const left = helmKeys.has('ArrowLeft');
|
||||||
if (magnitude < 0.28) return [1, 1];
|
const right = helmKeys.has('ArrowRight');
|
||||||
|
const up = helmKeys.has('ArrowUp');
|
||||||
|
const down = helmKeys.has('ArrowDown');
|
||||||
|
|
||||||
const sector = Math.round(Math.atan2(y, x) / (Math.PI / 4));
|
const column = left && !right ? 0 : right && !left ? 2 : 1;
|
||||||
const frames = {
|
const row = up && !down ? 0 : down && !up ? 2 : 1;
|
||||||
0: [2, 1],
|
|
||||||
1: [2, 2],
|
|
||||||
2: [1, 2],
|
|
||||||
3: [0, 2],
|
|
||||||
4: [0, 1],
|
|
||||||
'-4': [0, 1],
|
|
||||||
'-3': [0, 0],
|
|
||||||
'-2': [1, 0],
|
|
||||||
'-1': [2, 0],
|
|
||||||
};
|
|
||||||
return frames[sector] || [1, 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
const setHelmFrame = (x, y, immediate = false) => {
|
|
||||||
const [column, row] = resolveHelmFrame(x, y);
|
|
||||||
const key = `${column}:${row}`;
|
|
||||||
|
|
||||||
if (key === helmFrame) {
|
|
||||||
pendingHelmFrame = null;
|
|
||||||
if (helmFrameTimer) clearTimeout(helmFrameTimer);
|
|
||||||
helmFrameTimer = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (immediate) {
|
|
||||||
pendingHelmFrame = null;
|
|
||||||
if (helmFrameTimer) clearTimeout(helmFrameTimer);
|
|
||||||
helmFrameTimer = null;
|
|
||||||
applyHelmFrame(column, row);
|
applyHelmFrame(column, row);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pendingHelmFrame === key) return;
|
|
||||||
pendingHelmFrame = key;
|
|
||||||
if (helmFrameTimer) clearTimeout(helmFrameTimer);
|
|
||||||
helmFrameTimer = setTimeout(() => {
|
|
||||||
if (pendingHelmFrame === key) applyHelmFrame(column, row);
|
|
||||||
pendingHelmFrame = null;
|
|
||||||
helmFrameTimer = null;
|
|
||||||
}, 70);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let helmPointer = null;
|
const onHelmKeyDown = (event) => {
|
||||||
const updateHelmFrame = (event) => {
|
if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) return;
|
||||||
if (!stick) return;
|
helmKeys.add(event.code);
|
||||||
const rect = stick.getBoundingClientRect();
|
updateHelmFromKeys();
|
||||||
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) => {
|
const onHelmKeyUp = (event) => {
|
||||||
helmPointer = event.pointerId;
|
if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) return;
|
||||||
updateHelmFrame(event);
|
helmKeys.delete(event.code);
|
||||||
|
updateHelmFromKeys();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('keydown', onHelmKeyDown);
|
||||||
|
window.addEventListener('keyup', onHelmKeyUp);
|
||||||
|
window.addEventListener('blur', () => {
|
||||||
|
helmKeys.clear();
|
||||||
|
applyHelmFrame(1, 1);
|
||||||
});
|
});
|
||||||
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, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
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';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user