/* 贪蛇出动 - 输入控制:左摇杆 + 右加速按钮 + 桌面键盘 */ (function () { 'use strict'; window.GS = window.GS || {}; class Input { constructor() { this.angle = -Math.PI / 2; // 目标方向 this.boost = false; this.enabled = false; this._joyId = null; this._joyBase = { x: 0, y: 0 }; this._keys = new Set(); this._bind(); } _bind() { const joy = document.getElementById('gs-joystick'); const knob = document.getElementById('gs-joystick-knob'); const boostBtn = document.getElementById('gs-boost'); this.joyEl = joy; this.knobEl = knob; this.boostEl = boostBtn; // 摇杆:触摸左下区域 joy.addEventListener('touchstart', e => { e.preventDefault(); const t = e.changedTouches[0]; this._joyId = t.identifier; const r = joy.getBoundingClientRect(); this._joyBase = { x: r.left + r.width / 2, y: r.top + r.height / 2 }; this._moveKnob(t.clientX, t.clientY); }, { passive: false }); joy.addEventListener('touchmove', e => { e.preventDefault(); for (const t of e.changedTouches) if (t.identifier === this._joyId) this._moveKnob(t.clientX, t.clientY); }, { passive: false }); const endJoy = e => { for (const t of e.changedTouches) if (t.identifier === this._joyId) { this._joyId = null; this.knobEl.style.transform = 'translate(-50%, -50%)'; } }; joy.addEventListener('touchend', endJoy); joy.addEventListener('touchcancel', endJoy); // 桌面鼠标拖拽摇杆 let mouseDown = false; joy.addEventListener('mousedown', e => { mouseDown = true; const r = joy.getBoundingClientRect(); this._joyBase = { x: r.left + r.width / 2, y: r.top + r.height / 2 }; this._moveKnob(e.clientX, e.clientY); }); window.addEventListener('mousemove', e => { if (mouseDown) this._moveKnob(e.clientX, e.clientY); }); window.addEventListener('mouseup', () => { mouseDown = false; this.knobEl.style.transform = 'translate(-50%, -50%)'; }); // 加速按钮:按住加速 const boostOn = e => { e.preventDefault(); this.boost = true; boostBtn.classList.add('active'); }; const boostOff = () => { this.boost = false; boostBtn.classList.remove('active'); }; boostBtn.addEventListener('touchstart', boostOn, { passive: false }); boostBtn.addEventListener('touchend', boostOff); boostBtn.addEventListener('touchcancel', boostOff); boostBtn.addEventListener('mousedown', boostOn); boostBtn.addEventListener('mouseup', boostOff); boostBtn.addEventListener('mouseleave', boostOff); // 键盘(桌面调试):方向键/WSAD 转向,空格加速 window.addEventListener('keydown', e => { this._keys.add(e.code); if (e.code === 'Space') { this.boost = true; boostBtn.classList.add('active'); } this._applyKeys(); }); window.addEventListener('keyup', e => { this._keys.delete(e.code); if (e.code === 'Space') { this.boost = false; boostBtn.classList.remove('active'); } this._applyKeys(); }); // 阻止页面滚动/双击缩放 document.addEventListener('touchmove', e => { e.preventDefault(); }, { passive: false }); document.addEventListener('gesturestart', e => e.preventDefault()); } _applyKeys() { let dx = 0, dy = 0; if (this._keys.has('ArrowLeft') || this._keys.has('KeyA')) dx -= 1; if (this._keys.has('ArrowRight') || this._keys.has('KeyD')) dx += 1; if (this._keys.has('ArrowUp') || this._keys.has('KeyW')) dy -= 1; if (this._keys.has('ArrowDown') || this._keys.has('KeyS')) dy += 1; if (dx || dy) this.angle = Math.atan2(dy, dx); } _moveKnob(cx, cy) { const maxR = 40; let dx = cx - this._joyBase.x, dy = cy - this._joyBase.y; const d = Math.sqrt(dx * dx + dy * dy); if (d > maxR) { dx = dx / d * maxR; dy = dy / d * maxR; } this.knobEl.style.transform = `translate(calc(-50% + ${dx}px), calc(-50% + ${dy}px))`; if (d > 8) this.angle = Math.atan2(dy, dx); } setVisible(v) { this.enabled = v; this.joyEl.classList.toggle('gs-hidden', !v); this.boostEl.classList.toggle('gs-hidden', !v); } } GS.Input = Input; })();