67 lines
2.5 KiB
JavaScript
67 lines
2.5 KiB
JavaScript
// ==================== УПРАВЛЕНИЕ 3D — клавиатура + мышь ====================
|
|
// Клавиши работают напрямую через state.inp.fwd / state.inp.side (аналоговые оси -1..1),
|
|
// поэтому движение на компе идёт по той же схеме, что и джойстик на телефоне.
|
|
import { state } from '../core/state.js';
|
|
|
|
// клавиши, которые не должны скроллить страницу/открывать меню
|
|
const SWALLOW = new Set([
|
|
'Space', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',
|
|
'KeyW', 'KeyA', 'KeyS', 'KeyD',
|
|
]);
|
|
|
|
// истина, если игрок сейчас печатает в поле ввода
|
|
function typing() {
|
|
const el = document.activeElement;
|
|
if (!el) return false;
|
|
const t = el.tagName;
|
|
return t === 'INPUT' || t === 'TEXTAREA' || el.isContentEditable;
|
|
}
|
|
|
|
function applyKey(code, down) {
|
|
const inp = state.inp;
|
|
switch (code) {
|
|
// движение вперёд/назад и влево/вправо — по камере
|
|
case 'KeyW': case 'ArrowUp': inp.kfwd = down ? -1 : 0; break;
|
|
case 'KeyS': case 'ArrowDown': inp.kfwd = down ? 1 : 0; break;
|
|
case 'KeyA': case 'ArrowLeft': inp.kside = down ? -1 : 0; break;
|
|
case 'KeyD': case 'ArrowRight': inp.kside = down ? 1 : 0; break;
|
|
// прыжок
|
|
case 'Space': case 'KeyZ': inp.j = down; break;
|
|
// спуск по лестнице / вниз
|
|
case 'ShiftLeft': case 'KeyC': inp.s = down; break;
|
|
default: return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function initControls() {
|
|
window.addEventListener('keydown', (e) => {
|
|
if (typing()) return;
|
|
if (e.repeat) return;
|
|
if (SWALLOW.has(e.code)) e.preventDefault();
|
|
applyKey(e.code, true);
|
|
});
|
|
|
|
window.addEventListener('keyup', (e) => {
|
|
if (typing()) return;
|
|
applyKey(e.code, false);
|
|
});
|
|
|
|
// если окно потеряло фокус — сбрасываем всё, иначе персонаж «убегает» сам
|
|
window.addEventListener('blur', () => {
|
|
const inp = state.inp;
|
|
inp.kfwd = 0; inp.kside = 0; inp.j = false; inp.s = false;
|
|
});
|
|
|
|
// на всякий случай дублируем на document (фокус может быть на канвасе)
|
|
document.addEventListener('keydown', (e) => {
|
|
if (typing()) return;
|
|
if (e.repeat) return;
|
|
applyKey(e.code, true);
|
|
});
|
|
document.addEventListener('keyup', (e) => {
|
|
if (typing()) return;
|
|
applyKey(e.code, false);
|
|
});
|
|
}
|