Files
yangxiangyuan 6dc79a2c12 feat: 新增多项功能并添加新工具
- 私人剪贴板新增限时直通URL生成功能
- doc_cloud_keeper新增标题复制按钮
- 新增贪蛇出动游戏工具
- 新增OSS中转直链工具
- 添加批量抽帧测试脚本
2026-08-11 10:22:31 +08:00

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;
})();