6dc79a2c12
- 私人剪贴板新增限时直通URL生成功能 - doc_cloud_keeper新增标题复制按钮 - 新增贪蛇出动游戏工具 - 新增OSS中转直链工具 - 添加批量抽帧测试脚本
110 lines
4.3 KiB
JavaScript
110 lines
4.3 KiB
JavaScript
/* 贪蛇出动 - 输入控制:左摇杆 + 右加速按钮 + 桌面键盘 */
|
|
(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;
|
|
})();
|