-
-
-
-
+
+
-
-
-
+
+
+
+
+
-
@@ -226,37 +300,74 @@
console.error('Errore:', err);
});
- // WasmBoy native: Z=A, X=B, Enter=Start, Space=Select
- const bindButton = (id, keyDef) => {
- const btn = document.getElementById(id);
- const trigger = (type) => (e) => {
- e.preventDefault();
- let ev;
- try {
- ev = new KeyboardEvent(type, { key: keyDef.key, code: keyDef.code, bubbles: true, cancelable: true });
- } catch (e) {
- ev = document.createEvent('KeyboardEvent');
- ev.initKeyboardEvent(type, true, true, window, keyDef.key, 0, false, false, false, false);
- }
- document.dispatchEvent(ev);
- };
- btn.addEventListener('touchstart', trigger('keydown'), { passive: false });
- btn.addEventListener('touchend', trigger('keyup'), { passive: false });
- btn.addEventListener('mousedown', trigger('keydown'));
- btn.addEventListener('mouseup', trigger('keyup'));
- btn.addEventListener('mouseleave', trigger('keyup'));
+ /* ============================================
+ Universal button binder (data-key driven)
+ - Touch: synthetic keydown/keyup events
+ - Mouse: same
+ - Visual feedback: .pressed class
+ - Multi-touch: each button tracks its own state
+ ============================================ */
+ const KEY_CODE = {
+ 'ArrowUp':'ArrowUp','ArrowDown':'ArrowDown','ArrowLeft':'ArrowLeft','ArrowRight':'ArrowRight',
+ 'z':'KeyZ','Z':'KeyZ',
+ 'x':'KeyX','X':'KeyX',
+ 'Enter':'Enter','enter':'Enter',
+ ' ':'Space'
+ };
+ const KEY_KEY = {
+ 'ArrowUp':'ArrowUp','ArrowDown':'ArrowDown','ArrowLeft':'ArrowLeft','ArrowRight':'ArrowRight',
+ 'z':'z','Z':'z',
+ 'x':'x','X':'x',
+ 'Enter':'Enter','enter':'Enter',
+ ' ':' '
};
- bindButton('btn-up', { key: 'ArrowUp', code: 'ArrowUp' });
- bindButton('btn-down', { key: 'ArrowDown', code: 'ArrowDown' });
- bindButton('btn-left', { key: 'ArrowLeft', code: 'ArrowLeft' });
- bindButton('btn-right', { key: 'ArrowRight', code: 'ArrowRight' });
- bindButton('btn-a', { key: 'z', code: 'KeyZ' });
- bindButton('btn-b', { key: 'x', code: 'KeyX' });
- bindButton('btn-start', { key: 'Enter', code: 'Enter' });
- bindButton('btn-select',{ key: ' ', code: 'Space' });
+ function dispatchKey(type, dataKey) {
+ const ev = new KeyboardEvent(type, {
+ key: KEY_KEY[dataKey] || dataKey,
+ code: KEY_CODE[dataKey] || dataKey,
+ bubbles: true,
+ cancelable: true,
+ composed: true
+ });
+ document.dispatchEvent(ev);
+ }
- // Fullscreen toggle
+ document.querySelectorAll('.tbtn[data-key]').forEach(btn => {
+ const dataKey = btn.dataset.key;
+ let pressed = false;
+ const press = (e) => {
+ if (e) { e.preventDefault(); e.stopPropagation(); }
+ if (pressed) return;
+ pressed = true;
+ btn.classList.add('pressed');
+ dispatchKey('keydown', dataKey);
+ };
+ const release = (e) => {
+ if (e) { e.preventDefault(); e.stopPropagation(); }
+ if (!pressed) return;
+ pressed = false;
+ btn.classList.remove('pressed');
+ dispatchKey('keyup', dataKey);
+ };
+ // Touch (primary)
+ btn.addEventListener('touchstart', press, { passive: false });
+ btn.addEventListener('touchend', release, { passive: false });
+ btn.addEventListener('touchcancel',release, { passive: false });
+ // Mouse (fallback per emulatori desktop e testing)
+ btn.addEventListener('mousedown', press);
+ btn.addEventListener('mouseup', release);
+ btn.addEventListener('mouseleave', release);
+ // Keyboard accessibility (Enter/Space su button = click = simulate tap)
+ btn.addEventListener('click', e => e.preventDefault()); // niente click reale
+ });
+
+ // Prevent default for arrow keys (avoid page scroll on Space/Arrows)
+ window.addEventListener('keydown', e => {
+ if (['ArrowUp','ArrowDown','ArrowLeft','ArrowRight',' '].includes(e.key)) e.preventDefault();
+ }, { passive: false });
+
+ /* Fullscreen toggle */
const gameContainer = document.getElementById('game-container');
const fsButton = document.getElementById('btn-fullscreen');
fsButton.addEventListener('click', () => {