Files
InfoGenie/InfoGenie-frontend/public/smallgame/俄罗斯方块/game-controls.js
2025-09-16 09:14:04 +08:00

280 lines
8.1 KiB
JavaScript
Executable File

// 游戏控制模块
class GameControls {
constructor(game) {
this.game = game;
this.keys = {};
this.keyRepeatDelay = 150;
this.keyRepeatInterval = 50;
this.keyTimers = {};
this.init();
}
init() {
this.setupKeyboardControls();
this.setupTouchControls();
this.setupButtonControls();
}
setupKeyboardControls() {
document.addEventListener('keydown', (e) => {
this.handleKeyDown(e);
});
document.addEventListener('keyup', (e) => {
this.handleKeyUp(e);
});
}
handleKeyDown(e) {
const key = e.key;
// 防止重复触发
if (this.keys[key]) return;
this.keys[key] = true;
switch(key) {
case 'ArrowLeft':
e.preventDefault();
this.game.moveLeft();
this.startKeyRepeat('ArrowLeft', () => this.game.moveLeft());
break;
case 'ArrowRight':
e.preventDefault();
this.game.moveRight();
this.startKeyRepeat('ArrowRight', () => this.game.moveRight());
break;
case 'ArrowDown':
e.preventDefault();
this.game.moveDown();
this.startKeyRepeat('ArrowDown', () => this.game.moveDown());
break;
case 'ArrowUp':
e.preventDefault();
this.game.rotatePiece();
break;
case ' ':
e.preventDefault();
if (this.game.gameRunning) {
this.game.pause();
}
break;
case 'Enter':
e.preventDefault();
if (!this.game.gameRunning) {
this.game.start();
}
break;
case 'r':
case 'R':
if (e.ctrlKey) {
e.preventDefault();
this.game.restart();
}
break;
case 'Escape':
e.preventDefault();
if (this.game.gameRunning) {
this.game.pause();
}
break;
}
}
handleKeyUp(e) {
const key = e.key;
this.keys[key] = false;
this.stopKeyRepeat(key);
}
startKeyRepeat(key, action) {
this.stopKeyRepeat(key);
this.keyTimers[key] = setTimeout(() => {
const intervalId = setInterval(() => {
if (this.keys[key]) {
action();
} else {
clearInterval(intervalId);
}
}, this.keyRepeatInterval);
this.keyTimers[key] = intervalId;
}, this.keyRepeatDelay);
}
stopKeyRepeat(key) {
if (this.keyTimers[key]) {
clearTimeout(this.keyTimers[key]);
clearInterval(this.keyTimers[key]);
delete this.keyTimers[key];
}
}
setupTouchControls() {
// 移动端触摸控制
const leftBtn = document.getElementById('leftBtn');
const rightBtn = document.getElementById('rightBtn');
const downBtn = document.getElementById('downBtn');
const rotateBtn = document.getElementById('rotateBtn');
const dropBtn = document.getElementById('dropBtn');
const pauseBtn = document.getElementById('pauseBtn');
// 左移
this.addTouchEvents(leftBtn, () => this.game.moveLeft());
// 右移
this.addTouchEvents(rightBtn, () => this.game.moveRight());
// 下移
this.addTouchEvents(downBtn, () => this.game.moveDown());
// 旋转
rotateBtn.addEventListener('touchstart', (e) => {
e.preventDefault();
this.game.rotatePiece();
});
rotateBtn.addEventListener('click', (e) => {
e.preventDefault();
this.game.rotatePiece();
});
// 硬降
dropBtn.addEventListener('touchstart', (e) => {
e.preventDefault();
this.game.hardDrop();
});
dropBtn.addEventListener('click', (e) => {
e.preventDefault();
this.game.hardDrop();
});
// 暂停
pauseBtn.addEventListener('touchstart', (e) => {
e.preventDefault();
this.game.pause();
});
pauseBtn.addEventListener('click', (e) => {
e.preventDefault();
this.game.pause();
});
}
addTouchEvents(element, action) {
let touchInterval;
let touchTimeout;
const startAction = (e) => {
e.preventDefault();
action();
touchTimeout = setTimeout(() => {
touchInterval = setInterval(action, this.keyRepeatInterval);
}, this.keyRepeatDelay);
};
const stopAction = (e) => {
e.preventDefault();
if (touchTimeout) {
clearTimeout(touchTimeout);
touchTimeout = null;
}
if (touchInterval) {
clearInterval(touchInterval);
touchInterval = null;
}
};
element.addEventListener('touchstart', startAction);
element.addEventListener('touchend', stopAction);
element.addEventListener('touchcancel', stopAction);
element.addEventListener('mousedown', startAction);
element.addEventListener('mouseup', stopAction);
element.addEventListener('mouseleave', stopAction);
}
setupButtonControls() {
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
startBtn.addEventListener('click', () => {
this.game.start();
});
restartBtn.addEventListener('click', () => {
this.game.restart();
});
}
// 游戏手势支持
setupSwipeControls() {
let startX = 0;
let startY = 0;
let threshold = 50;
this.game.canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
const touch = e.touches[0];
startX = touch.clientX;
startY = touch.clientY;
});
this.game.canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
});
this.game.canvas.addEventListener('touchend', (e) => {
e.preventDefault();
const touch = e.changedTouches[0];
const deltaX = touch.clientX - startX;
const deltaY = touch.clientY - startY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 水平滑动
if (Math.abs(deltaX) > threshold) {
if (deltaX > 0) {
this.game.moveRight();
} else {
this.game.moveLeft();
}
}
} else {
// 垂直滑动
if (Math.abs(deltaY) > threshold) {
if (deltaY > 0) {
this.game.moveDown();
} else {
this.game.rotatePiece();
}
}
}
});
// 双击旋转
let lastTap = 0;
this.game.canvas.addEventListener('touchend', (e) => {
const currentTime = new Date().getTime();
const tapLength = currentTime - lastTap;
if (tapLength < 500 && tapLength > 0) {
e.preventDefault();
this.game.rotatePiece();
}
lastTap = currentTime;
});
}
}
// 初始化控制系统
const gameControls = new GameControls(game);