Files
2026-02-25 22:24:59 -05:00

265 lines
10 KiB
JavaScript

// Input handler
class InputHandler {
constructor(game) {
this.game = game;
this.touchStartX = 0;
this.touchStartY = 0;
this.isTouching = false;
this.bindEvents();
}
bindEvents() {
// Keyboard controls
document.addEventListener('keydown', (e) => this.handleKeyPress(e));
// Mouse movement view control - edge trigger
const gameScreen = document.getElementById('game-screen');
gameScreen.addEventListener('mousemove', (e) => this.handleMouseMove(e));
// Touch controls for mobile
gameScreen.addEventListener('touchstart', (e) => this.handleTouchStart(e), { passive: false });
gameScreen.addEventListener('touchmove', (e) => this.handleTouchMove(e), { passive: false });
gameScreen.addEventListener('touchend', (e) => this.handleTouchEnd(e), { passive: false });
}
handleKeyPress(e) {
// ==================== 作弊键(生产环境请注释掉) ====================
/* // F6 作弊键:立即触发特朗普进入管道(测试音效用)
if (e.key === 'F6') {
e.preventDefault();
if (this.game.state.isGameRunning && this.game.enemyAI.trump.hasSpawned) {
console.log('🎮 CHEAT: Forcing Trump to crawl into vents...');
this.showCheatNotification('Trump entering vents NOW!');
// 强制特朗普从 cam1 开始爬行
this.game.enemyAI.trump.currentLocation = 'cam1';
// 立即播放音效(不等待延迟)- 音量改为1.0(最大值)
console.log('Playing crawling sound immediately...');
this.game.assets.playSound('ventCrawling', true, 1.0);
// 10秒后停止音效
setTimeout(() => {
console.log('Stopping crawling sound...');
this.game.assets.stopSound('ventCrawling');
}, 10000);
} else if (this.game.state.isGameRunning) {
this.showCheatNotification('Trump not spawned yet!');
}
return;
}
// F9 作弊键:跳过当前夜晚(调试用)
if (e.key === 'F9') {
e.preventDefault();
if (this.game.state.isGameRunning) {
console.log('🎮 CHEAT: Skipping current night...');
// 显示作弊提示
this.showCheatNotification('Skipping Night ' + this.game.state.currentNight);
// 延迟执行,让玩家看到提示
setTimeout(() => {
this.game.winNight();
}, 500);
}
return;
}
// F10 作弊键:解锁特殊夜晚(调试用)
if (e.key === 'F10') {
e.preventDefault();
console.log('🎮 CHEAT: Unlocking Special Night...');
localStorage.setItem('night6Unlocked', 'true');
this.showCheatNotification('Special Night Unlocked!');
// 如果在主菜单,立即更新按钮显示
if (this.game.mainMenu && !this.game.mainMenu.classList.contains('hidden')) {
this.game.updateContinueButton();
}
return;
}
// F8 作弊键:解锁Custom Night(调试用)
if (e.key === 'F8') {
e.preventDefault();
console.log('🎮 CHEAT: Unlocking Custom Night...');
localStorage.setItem('night6Completed', 'true');
this.showCheatNotification('Custom Night Unlocked!');
// 如果在主菜单,立即更新按钮显示
if (this.game.mainMenu && !this.game.mainMenu.classList.contains('hidden')) {
this.game.updateContinueButton();
}
return;
}
// F7 作弊键:时间加速(测试用)
if (e.key === 'F7') {
e.preventDefault();
if (this.game.state.isGameRunning) {
this.game.state.currentTime += 1;
this.game.ui.update();
this.showCheatNotification(`Time: ${this.game.state.currentTime} AM`);
if (this.game.state.currentTime >= 6) {
this.game.winNight();
}
}
return;
}
// 数字键1-6:快速跳到对应关卡(测试用,仅在主菜单有效)
if (e.key >= '1' && e.key <= '6') {
if (this.game.mainMenu && !this.game.mainMenu.classList.contains('hidden')) {
e.preventDefault();
const night = parseInt(e.key);
console.log(`🎮 CHEAT: Jumping to Night ${night}...`);
this.game.state.currentNight = night;
this.showCheatNotification(`Starting Night ${night}`);
// 如果是Night 6,需要先解锁
if (night === 6) {
localStorage.setItem('night6Unlocked', 'true');
setTimeout(() => this.game.startSpecialNight(), 500);
} else {
setTimeout(() => this.game.initGame(), 500);
}
this.game.mainMenu.classList.add('hidden');
const menuMusic = document.getElementById('menu-music');
if (menuMusic) {
menuMusic.pause();
menuMusic.currentTime = 0;
}
}
return;
} */
// ==================== 作弊键结束 ====================
if (!this.game.state.isGameRunning) return;
switch(e.key.toLowerCase()) {
case 'v':
this.game.toggleVents();
break;
case ' ':
e.preventDefault();
this.game.toggleCamera();
break;
}
}
// 作弊通知
showCheatNotification(message) {
// 创建通知元素
const notification = document.createElement('div');
notification.style.position = 'fixed';
notification.style.top = '10px';
notification.style.left = '50%';
notification.style.transform = 'translateX(-50%)';
notification.style.background = 'rgba(255, 215, 0, 0.9)';
notification.style.color = '#000';
notification.style.padding = '10px 20px';
notification.style.fontSize = '20px';
notification.style.fontWeight = 'bold';
notification.style.fontFamily = 'Arial, sans-serif';
notification.style.borderRadius = '5px';
notification.style.zIndex = '99999';
notification.style.boxShadow = '0 0 20px rgba(255, 215, 0, 0.8)';
notification.textContent = '🎮 CHEAT: ' + message;
document.body.appendChild(notification);
// 1秒后移除
setTimeout(() => {
notification.remove();
}, 1000);
}
handleMouseMove(e) {
if (!this.game.state.isGameRunning || this.game.state.cameraOpen) return;
const edgeThreshold = 100;
const mouseX = e.clientX;
const screenWidth = window.innerWidth;
// Check if at left edge
if (mouseX < edgeThreshold) {
this.game.isRotatingLeft = true;
this.game.isRotatingRight = false;
}
// Check if at right edge
else if (mouseX > screenWidth - edgeThreshold) {
this.game.isRotatingRight = true;
this.game.isRotatingLeft = false;
}
// In middle area, stop rotation
else {
this.game.isRotatingLeft = false;
this.game.isRotatingRight = false;
}
}
handleTouchStart(e) {
if (!this.game.state.isGameRunning || this.game.state.cameraOpen) return;
// Don't prevent default if touching UI elements
const target = e.target;
if (target.closest('.hotspot') || target.closest('.control-panel-button') ||
target.closest('.camera-button') || target.closest('#control-panel-popup')) {
return;
}
e.preventDefault();
const touch = e.touches[0];
this.touchStartX = touch.clientX;
this.touchStartY = touch.clientY;
this.isTouching = true;
}
handleTouchMove(e) {
if (!this.game.state.isGameRunning || this.game.state.cameraOpen || !this.isTouching) return;
// Don't prevent default if touching UI elements
const target = e.target;
if (target.closest('.hotspot') || target.closest('.control-panel-button') ||
target.closest('.camera-button') || target.closest('#control-panel-popup')) {
return;
}
e.preventDefault();
const touch = e.touches[0];
const deltaX = touch.clientX - this.touchStartX;
const deltaY = Math.abs(touch.clientY - this.touchStartY);
// Only rotate if horizontal swipe (not vertical)
if (deltaY < 50) {
const sensitivity = 0.002;
// Reverse the direction: swipe right = view right, swipe left = view left
const movement = -deltaX * sensitivity;
// Update view position directly
this.game.viewPosition += movement;
this.game.viewPosition = Math.max(0, Math.min(1, this.game.viewPosition));
this.game.ui.updateViewPosition(this.game.viewPosition);
// Update touch start position for smooth continuous movement
this.touchStartX = touch.clientX;
this.touchStartY = touch.clientY;
}
}
handleTouchEnd(e) {
if (!this.game.state.isGameRunning) return;
this.isTouching = false;
this.game.isRotatingLeft = false;
this.game.isRotatingRight = false;
}
}