AI生成游戏 鬼屋寻宝!
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>鬼屋寻宝</title> <style> body { font-family: 'Courier New', Courier, monospace; background-color: #1a1a1a; color: #f0f0f0; margin: 0; display: flex; flex-direction: column; align-items: center; min-height: 100vh; } .game-container { width: 90%; max-width: 1000px; display: flex; flex-direction: column; gap: 20px; } .header { text-align: center; margin-bottom: 10px; } .game-board { display: grid; grid-template-columns: 3fr 1fr; gap: 20px; } .maze-area { background-color: #2a2a2a; padding: 15px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); overflow: auto; } /* 修改迷宫显示方式为网格布局 */ .maze { display: grid; grid-gap: 0; justify-content: center; } /* 修改单元格样式,增强对比度 */ .cell { width: 28px; height: 28px; display: flex; justify-content: center; align-items: center; font-family: monospace; font-size: 18px; user-select: none; border: 1px solid #333; position: relative; overflow: hidden; } /* 显著提高墙壁和路径的视觉对比 */ .wall-cell { background-color: #4a4a4a; /* 更亮的灰色 */ box-shadow: inset 0 0 5px #333; border: 1px solid #555; background-image: linear-gradient(45deg, #424242 25%, #525252 25%, #525252 50%, #424242 50%, #424242 75%, #525252 75%, #525252); background-size: 10px 10px; /* 增大砖块图案 */ } .path-cell { background-color: #111111; /* 更暗的黑色 */ border: 1px solid #333; } /* 增强墙壁和路径的符号可见性 */ .wall { color: #cccccc; /* 更亮的墙壁文字 */ text-shadow: 0 0 3px #000; font-weight: bold; font-size: 20px; } .path { color: #444444; /* 更暗的路径文字 */ text-shadow: 0 0 2px #000; } .side-panel { display: flex; flex-direction: column; gap: 20px; } .status-area, .message-area, .controls-area { background-color: #2a2a2a; padding: 15px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); } .status-area h3, .message-area h3, .controls-area h3 { margin-top: 0; border-bottom: 1px solid #444; padding-bottom: 5px; } .message-area { height: 150px; overflow-y: auto; } .message { margin: 5px 0; padding: 5px; border-left: 3px solid #444; } .message.important { border-left-color: #ff5555; } /* 警告消息样式 */ .message.warning { border-left-color: #ff0000; background-color: rgba(255, 0, 0, 0.1); color: #ff5555; font-weight: bold; padding: 8px 5px; } .controls-area button { display: block; width: 100%; padding: 8px; margin: 5px 0; background-color: #3a3a3a; color: #f0f0f0; border: none; border-radius: 3px; cursor: pointer; transition: background-color 0.2s; } .controls-area button:hover { background-color: #4a4a4a; } .mobile-controls { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: 5px; margin-top: 10px; } .mobile-controls button { padding: 10px; } /* 修改图例样式,使其更清晰 */ .legend { display: flex; flex-wrap: wrap; gap: 15px; margin: 15px 0; justify-content: center; padding: 10px; background-color: #1a1a1a; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); } .legend-item { display: flex; align-items: center; gap: 8px; padding: 5px 10px; background-color: #242424; border-radius: 4px; border: 1px solid #333; } /* 调整图例中的墙壁和路径样式 */ .legend .wall-cell { width: 24px; height: 24px; } .legend .path-cell { width: 24px; height: 24px; } /* 确保迷宫内元素更容易识别 */ .player { color: #45aaf2; font-weight: bold; text-shadow: 0 0 5px rgba(69, 170, 242, 0.7); font-size: 20px; } .ghost { color: #ff6b6b; font-weight: bold; text-shadow: 0 0 5px rgba(255, 107, 107, 0.7); font-size: 20px; } .box { color: #fed330; font-weight: bold; text-shadow: 0 0 5px rgba(254, 211, 48, 0.7); font-size: 20px; } .door { color: #26de81; font-weight: bold; text-shadow: 0 0 5px rgba(38, 222, 129, 0.7); font-size: 20px; } /* 修改玩家可移动位置的高亮显示 */ .cell-highlight { animation: cellPulse 1s infinite alternate; background-color: #1a1f2c !important; /* 深蓝色调,覆盖其他背景 */ border: 1px solid #4a5568 !important; } @keyframes cellPulse { from { box-shadow: 0 0 2px 1px rgba(69, 170, 242, 0.3); } to { box-shadow: 0 0 5px 3px rgba(69, 170, 242, 0.6); } } .difficulty-selector { display: flex; justify-content: space-between; margin-bottom: 10px; } .difficulty-selector button { flex: 1; margin: 0 5px; padding: 8px; background-color: #3a3a3a; color: #f0f0f0; border: none; border-radius: 3px; cursor: pointer; } .difficulty-selector button.active { background-color: #4CAF50; } .game-over { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 100; color: white; } .game-over h2 { font-size: 36px; margin-bottom: 20px; } .game-over button { padding: 10px 20px; font-size: 18px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; } @media (max-width: 768px) { .game-board { grid-template-columns: 1fr; } .cell { width: 24px; /* 移动端更小的单元格 */ height: 24px; font-size: 16px; } .legend { flex-direction: column; align-items: flex-start; } } /* 为墙壁添加额外的视觉提示 */ .wall-cell::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: repeating-linear-gradient( -45deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1) 10px, rgba(0, 0, 0, 0.2) 10px, rgba(0, 0, 0, 0.2) 20px ); pointer-events: none; } </style> </head> <body> <div class="game-container"> <div class="header"> <h1>鬼屋寻宝</h1> </div> <div class="legend"> <div class="legend-item"> <div class="legend-icon path-cell"><span class="path">·</span></div> <span>可通行</span> </div> <div class="legend-item"> <div class="legend-icon wall-cell"><span class="wall">#</span></div> <span>墙壁</span> </div> <div class="legend-item"> <div class="legend-icon"><span class="player">我</span></div> <span>玩家</span> </div> <div class="legend-item"> <div class="legend-icon"><span class="box">箱</span></div> <span>箱子</span> </div> <div class="legend-item"> <div class="legend-icon"><span class="door">门</span></div> <span>门</span> </div> <div class="legend-item"> <div class="legend-icon"><span class="ghost">鬼</span></div> <span>鬼</span> </div> </div> <div class="game-board"> <div class="maze-area"> <div class="maze" id="maze"></div> </div> <div class="side-panel"> <div class="status-area"> <h3>状态</h3> <div id="status"> 钥匙: 0<br> 已打开箱子: 0 / 0<br> 安全状态: 是<br> </div> </div> <div class="message-area"> <h3>消息</h3> <div id="messages"></div> </div> <div class="controls-area"> <h3>控制</h3> <button id="start">开始新游戏</button> <div class="mobile-controls"> <button id="up">↑</button> <button id="left">←</button> <button id="action">行动</button> <button id="right">→</button> <button id="down">↓</button> </div> </div> </div> </div> </div> <script> // 游戏核心类 class BoxEscapeGame { constructor() { this.maze = []; this.width = 15; // 缩小地图尺寸到15x15 this.height = 15; this.player = { x: 0, y: 0 }; this.ghosts = []; this.boxes = []; this.doors = []; this.keys = 0; this.openedBoxes = 0; this.totalBoxes = 0; this.isPlayerInDoor = false; this.gameOver = false; this.victory = false; this.messages = []; this.playerInDanger = false; this.playerPath = []; this.setupEventListeners(); } // 初始化游戏 initGame() { this.gameOver = false; this.victory = false; this.keys = 0; this.openedBoxes = 0; this.ghosts = []; this.doors = []; this.isPlayerInDoor = false; this.playerInDanger = false; this.playerPath = []; // 生成迷宫 this.generateMaze(); // 放置玩家 this.placePlayer(); // 放置箱子 - 减少箱子数量到7个,适合小地图 this.placeBoxes(7); // 放置门 - 保持2个门 this.placeDoors(2); // 更新状态 this.updateStatus(); // 清空消息 this.clearMessages(); this.addMessage("游戏开始!使用方向键移动,空格键互动。", true); this.addMessage("找到并打开所有箱子,收集钥匙,小心鬼的追击!"); // 清除之前的定时器(如果存在) if (this.ghostMoveTimer) { clearInterval(this.ghostMoveTimer); } // 设置鬼的自动移动定时器 this.setupGhostTimer(); // 渲染迷宫 this.renderMaze(); } // 生成迷宫 (使用深度优先搜索算法) generateMaze() { // 初始化迷宫 (全部为墙) this.maze = []; for (let y = 0; y < this.height; y++) { let row = []; for (let x = 0; x < this.width; x++) { row.push('#'); } this.maze.push(row); } // 从随机点开始生成迷宫 let startX = Math.floor(Math.random() * Math.floor((this.width-1)/2)) * 2 + 1; let startY = Math.floor(Math.random() * Math.floor((this.height-1)/2)) * 2 + 1; this.maze[startY][startX] = ' '; // 深度优先搜索生成迷宫 let stack = [{x: startX, y: startY}]; while (stack.length > 0) { let current = stack[stack.length - 1]; let neighbors = this.getUnvisitedNeighbors(current.x, current.y); if (neighbors.length === 0) { stack.pop(); } else { let next = neighbors[Math.floor(Math.random() * neighbors.length)]; this.maze[next.y][next.x] = ' '; this.maze[current.y + (next.y - current.y)/2][current.x + (next.x - current.x)/2] = ' '; stack.push({x: next.x, y: next.y}); } } // 添加额外通道,增加多样性 for (let i = 0; i < this.width * this.height / 20; i++) { let x = Math.floor(Math.random() * (this.width - 2)) + 1; let y = Math.floor(Math.random() * (this.height - 2)) + 1; if (this.maze[y][x] === '#') { let adjacentPaths = 0; if (this.maze[y-1][x] === ' ') adjacentPaths++; if (this.maze[y+1][x] === ' ') adjacentPaths++; if (this.maze[y][x-1] === ' ') adjacentPaths++; if (this.maze[y][x+1] === ' ') adjacentPaths++; if (adjacentPaths >= 2) { this.maze[y][x] = ' '; } } } } // 获取未访问的邻居 (用于迷宫生成) getUnvisitedNeighbors(x, y) { let neighbors = []; let directions = [ {dx: 0, dy: -2}, // 上 {dx: 2, dy: 0}, // 右 {dx: 0, dy: 2}, // 下 {dx: -2, dy: 0} // 左 ]; for (let dir of directions) { let nx = x + dir.dx; let ny = y + dir.dy; if (nx >= 0 && nx < this.width && ny >= 0 && ny < this.height && this.maze[ny][nx] === '#') { neighbors.push({x: nx, y: ny}); } } return neighbors; } // 放置玩家 placePlayer() { // 找到一个空位置 let x, y; do { x = Math.floor(Math.random() * this.width); y = Math.floor(Math.random() * this.height); } while (this.maze[y][x] !== ' '); this.player = {x, y}; } // 放置箱子 placeBoxes(boxCount) { this.boxes = []; this.totalBoxes = boxCount; for (let i = 0; i < boxCount; i++) { // 找到一个空位置放箱子 let x, y; let attempts = 0; const maxAttempts = 100; do { x = Math.floor(Math.random() * this.width); y = Math.floor(Math.random() * this.height); attempts++; // 避免无限循环 if (attempts > maxAttempts) break; } while ( this.maze[y][x] !== ' ' || (this.player.x === x && this.player.y === y) || this.boxes.some(box => box.x === x && box.y === y) ); // 如果找到有效位置,添加箱子 if (attempts <= maxAttempts) { this.boxes.push({x, y}); } } } // 放置门 placeDoors(doorCount) { this.doors = []; for (let i = 0; i < doorCount; i++) { // 找到一个空位置放门 let x, y; let attempts = 0; const maxAttempts = 100; do { x = Math.floor(Math.random() * this.width); y = Math.floor(Math.random() * this.height); attempts++; if (attempts > maxAttempts) break; } while ( this.maze[y][x] !== ' ' || (this.player.x === x && this.player.y === y) || this.boxes.some(box => box.x === x && box.y === y) || this.doors.some(door => door.x === x && door.y === y) ); if (attempts <= maxAttempts) { this.doors.push({x, y, isOpen: false}); } } } // 渲染迷宫 - 使用网格布局替代文本 renderMaze() { let mazeElement = document.getElementById('maze'); // 清空迷宫 mazeElement.innerHTML = ""; // 设置网格列数 mazeElement.style.gridTemplateColumns = `repeat(${this.width}, 1fr)`; // 创建单元格 for (let y = 0; y < this.height; y++) { for (let x = 0; x < this.width; x++) { let cell = document.createElement('div'); // 根据单元格类型设置样式 if (this.maze[y][x] === '#') { cell.className = 'cell wall-cell'; } else { cell.className = 'cell path-cell'; } // 高亮显示玩家当前可移动的相邻单元格 if (this.maze[y][x] === ' ' && ((Math.abs(x - this.player.x) === 1 && y === this.player.y) || (Math.abs(y - this.player.y) === 1 && x === this.player.x))) { cell.classList.add('cell-highlight'); } // 检查格子中的特殊对象 if (this.player.x === x && this.player.y === y) { // 如果玩家处于危险状态,添加危险类 let playerClass = this.playerInDanger ? "player in-danger" : "player"; cell.innerHTML = `<span class="${playerClass}">我</span>`; } else if (this.boxes.some(box => box.x === x && box.y === y)) { cell.innerHTML = '<span class="box">箱</span>'; } else if (this.doors.some(door => door.x === x && door.y === y)) { let door = this.doors.find(door => door.x === x && door.y === y); if (door.isOpen) { cell.innerHTML = '<span class="door">开</span>'; } else { cell.innerHTML = '<span class="door">门</span>'; } } else if (this.ghosts.some(ghost => ghost.x === x && ghost.y === y)) { cell.innerHTML = '<span class="ghost">鬼</span>'; } else if (this.maze[y][x] === '#') { cell.innerHTML = '<span class="wall">#</span>'; } else { cell.innerHTML = '<span class="path">·</span>'; } mazeElement.appendChild(cell); } } } // 更新游戏状态显示 updateStatus() { let statusElement = document.getElementById('status'); statusElement.innerHTML = ` 钥匙: ${this.keys}<br> 已打开箱子: ${this.openedBoxes} / ${this.totalBoxes}<br> 安全状态: ${this.isPlayerInDoor ? '是 (在门内)' : this.playerInDanger ? '否 (危险!)' : '否'}<br> `; } // 添加消息 addMessage(message, important = false, warning = false) { let className = warning ? "message warning" : (important ? "message important" : "message"); this.messages.unshift({ text: message, className }); if (this.messages.length > 10) { this.messages.pop(); } let messagesElement = document.getElementById('messages'); let messageHTML = ""; for (let msg of this.messages) { messageHTML += `<div class="${msg.className}">${msg.text}</div>`; } messagesElement.innerHTML = messageHTML; } // 清空消息 clearMessages() { this.messages = []; document.getElementById('messages').innerHTML = ""; } // 移动玩家 movePlayer(dx, dy) { if (this.gameOver) return; let newX = this.player.x + dx; let newY = this.player.y + dy; // 检查是否可以移动 if (newX >= 0 && newX < this.width && newY >= 0 && newY < this.height && this.maze[newY][newX] === ' ') { // 如果玩家在门里,离开门 if (this.isPlayerInDoor) { this.isPlayerInDoor = false; this.addMessage("你离开了门,不再安全了!", true); } // 记录玩家移动前的位置到路径中 this.playerPath.push({x: this.player.x, y: this.player.y}); // 限制路径长度,防止过长 if (this.playerPath.length > 50) { this.playerPath.shift(); } this.player.x = newX; this.player.y = newY; // 检查是否踩到箱子 let boxIndex = this.boxes.findIndex(box => box.x === newX && box.y === newY); if (boxIndex !== -1) { this.openBox(boxIndex); } // 检查是否踩到门 let doorIndex = this.doors.findIndex(door => door.x === newX && door.y === newY); if (doorIndex !== -1) { let door = this.doors[doorIndex]; if (door.isOpen) { this.enterDoor(doorIndex); } else if (this.keys > 0) { this.openDoor(doorIndex); } else { this.addMessage("这扇门是锁着的,需要钥匙才能打开。"); } } // 检查是否被鬼抓到 this.checkGhostCollision(); // 检查是否胜利 this.checkVictory(); // 渲染迷宫 this.renderMaze(); // 更新状态 this.updateStatus(); } else { // 如果是撞墙,添加提示 if (newX >= 0 && newX < this.width && newY >= 0 && newY < this.height && this.maze[newY][newX] === '#') { this.addMessage("那边是墙,不能通过。"); } } } // 执行交互动作 performAction() { if (this.gameOver) return; // 检查玩家周围的箱子 for (let i = 0; i < this.boxes.length; i++) { let box = this.boxes[i]; if (Math.abs(box.x - this.player.x) <= 1 && Math.abs(box.y - this.player.y) <= 1) { this.openBox(i); this.renderMaze(); this.updateStatus(); return; } } // 检查玩家周围的门 for (let i = 0; i < this.doors.length; i++) { let door = this.doors[i]; if (Math.abs(door.x - this.player.x) <= 1 && Math.abs(door.y - this.player.y) <= 1) { if (door.isOpen) { this.enterDoor(i); } else if (this.keys > 0) { this.openDoor(i); } else { this.addMessage("这扇门是锁着的,需要钥匙才能打开。"); } this.renderMaze(); this.updateStatus(); return; } } this.addMessage("周围没有可以互动的物品。"); } // 打开箱子 openBox(boxIndex) { let box = this.boxes[boxIndex]; // 从箱子列表中移除 this.boxes.splice(boxIndex, 1); // 记录已打开箱子数 this.openedBoxes++; // 随机事件 let rand = Math.random(); // 降低鬼出现概率到30% const ghostChance = 0.3; if (rand < ghostChance) { // 出现鬼 this.addMessage("你打开箱子,一个鬼跳了出来!", true, true); this.spawnGhost(box.x, box.y); } else if (rand < ghostChance + 0.4) { // 获得钥匙 this.keys++; this.addMessage("你打开箱子,找到了一把钥匙!", true); } else { // 箱子为空 this.addMessage("你打开箱子,但里面什么也没有。"); } } // 生成鬼 spawnGhost(x, y) { // 添加鬼,并设置三秒后开始追踪 this.ghosts.push({ x, y, countdown: 3, active: false // 鬼是否处于活动状态 }); // 玩家进入危险状态 this.playerInDanger = true; // 倒计时显示 this.addMessage("警告:鬼将在3秒后开始追击你!", true, true); setTimeout(() => { if (this.gameOver) return; let ghost = this.ghosts.find(ghost => ghost.x === x && ghost.y === y); if (ghost) { ghost.countdown = 2; this.addMessage("警告:鬼将在2秒后开始追击你!", true, true); } }, 1000); setTimeout(() => { if (this.gameOver) return; let ghost = this.ghosts.find(ghost => ghost.x === x && ghost.y === y); if (ghost) { ghost.countdown = 1; this.addMessage("警告:鬼将在1秒后开始追击你!", true, true); } }, 2000); setTimeout(() => { if (this.gameOver) return; let ghost = this.ghosts.find(ghost => ghost.x === x && ghost.y === y); if (ghost) { ghost.countdown = 0; ghost.active = true; this.addMessage("鬼开始移动了!快逃!", true, true); } }, 3000); } // 移动鬼 - 总是使用最优路径 moveGhosts() { for (let ghost of this.ghosts) { // 只有倒计时结束且激活的鬼才会移动 if (ghost.countdown > 0 || !ghost.active) continue; // 如果玩家在门里,鬼不会追踪 if (this.isPlayerInDoor) continue; // 使用BFS算法寻找最短路径到玩家 const nextMove = this.findShortestPathToPlayer(ghost); if (nextMove) { ghost.x = nextMove.x; ghost.y = nextMove.y; } else { // 如果BFS找不到路径,使用简单的启发式方法 this.moveGhostHeuristically(ghost); } } } // 使用BFS寻找到玩家的最短路径 findShortestPathToPlayer(ghost) { // 创建一个表示已访问单元格的二维数组 let visited = []; // 创建一个存储前一步的数组,用于重建路径 let previous = []; for (let y = 0; y < this.height; y++) { let visitedRow = []; let previousRow = []; for (let x = 0; x < this.width; x++) { visitedRow.push(false); previousRow.push(null); } visited.push(visitedRow); previous.push(previousRow); } // 创建队列并添加起始位置 let queue = [{x: ghost.x, y: ghost.y}]; visited[ghost.y][ghost.x] = true; // 方向数组 let directions = [ {dx: 0, dy: -1}, // 上 {dx: 1, dy: 0}, // 右 {dx: 0, dy: 1}, // 下 {dx: -1, dy: 0} // 左 ]; // BFS遍历 let found = false; while (queue.length > 0 && !found) { let current = queue.shift(); // 如果到达玩家位置 if (current.x === this.player.x && current.y === this.player.y) { found = true; break; } // 探索四个方向 for (let dir of directions) { let nx = current.x + dir.dx; let ny = current.y + dir.dy; // 检查是否是有效移动且未访问过 if (nx >= 0 && nx < this.width && ny >= 0 && ny < this.height && this.maze[ny][nx] === ' ' && !visited[ny][nx]) { // 标记为已访问 visited[ny][nx] = true; // 存储前一步 previous[ny][nx] = {x: current.x, y: current.y}; // 添加到队列 queue.push({x: nx, y: ny}); } } } // 如果找到了路径,重建路径并返回第一步 if (found) { // 从玩家位置回溯到鬼的位置 let path = []; let current = {x: this.player.x, y: this.player.y}; while (current && !(current.x === ghost.x && current.y === ghost.y)) { path.unshift(current); current = previous[current.y][current.x]; } // 返回路径上的第一步 if (path.length > 0) { return path[0]; } } // 如果没有找到路径 return null; } // 启发式移动方法(当BFS失败时的备用方案) moveGhostHeuristically(ghost) { let possibleMoves = []; let directions = [ {dx: 0, dy: -1}, // 上 {dx: 1, dy: 0}, // 右 {dx: 0, dy: 1}, // 下 {dx: -1, dy: 0} // 左 ]; for (let dir of directions) { let nx = ghost.x + dir.dx; let ny = ghost.y + dir.dy; // 检查是否可移动 if (nx >= 0 && nx < this.width && ny >= 0 && ny < this.height && this.maze[ny][nx] === ' ') { // 计算向玩家移动的曼哈顿距离 let currentDist = Math.abs(ghost.x - this.player.x) + Math.abs(ghost.y - this.player.y); let newDist = Math.abs(nx - this.player.x) + Math.abs(ny - this.player.y); possibleMoves.push({ x: nx, y: ny, isBetter: newDist < currentDist }); } } // 如果有可能的移动 if (possibleMoves.length > 0) { // 优先选择能减少与玩家距离的移动 let betterMoves = possibleMoves.filter(move => move.isBetter); let selectedMove; if (betterMoves.length > 0) { // 选择向玩家靠近的移动 selectedMove = betterMoves[Math.floor(Math.random() * betterMoves.length)]; } else { // 随机选择移动 selectedMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]; } // 移动鬼 ghost.x = selectedMove.x; ghost.y = selectedMove.y; } } // 检查鬼与玩家的碰撞 checkGhostCollision() { if (this.isPlayerInDoor) return; // 玩家在门内是安全的 for (let ghost of this.ghosts) { if (ghost.active && ghost.x === this.player.x && ghost.y === this.player.y) { this.gameOver = true; this.addMessage("你被鬼抓住了!游戏结束。", true, true); this.showGameOverScreen(false); return; } } } // 打开门 openDoor(doorIndex) { let door = this.doors[doorIndex]; if (!door.isOpen && this.keys > 0) { this.keys--; door.isOpen = true; this.addMessage("你用钥匙打开了门!"); } } // 进入门 enterDoor(doorIndex) { if (this.doors[doorIndex].isOpen) { this.isPlayerInDoor = true; this.playerInDanger = false; // 在门内不再危险 this.addMessage("你进入了门,在这里你是安全的!", true); } } // 检查胜利条件 checkVictory() { if (this.openedBoxes >= this.totalBoxes) { this.gameOver = true; this.victory = true; this.addMessage("恭喜!你成功打开了所有箱子并存活下来!", true); this.showGameOverScreen(true); } } // 显示游戏结束屏幕 showGameOverScreen(isVictory) { let gameOverDiv = document.createElement('div'); gameOverDiv.className = 'game-over'; if (isVictory) { gameOverDiv.innerHTML = ` <h2>胜利!</h2> <p>你成功打开了所有 ${this.totalBoxes} 个箱子并存活下来!</p> <button id="restart">再玩一次</button> `; } else { gameOverDiv.innerHTML = ` <h2>游戏结束</h2> <p>你被鬼抓住了!你只打开了 ${this.openedBoxes} 个箱子,还差 ${this.totalBoxes - this.openedBoxes} 个。</p> <button id="restart">再试一次</button> `; } document.body.appendChild(gameOverDiv); document.getElementById('restart').addEventListener('click', () => { document.body.removeChild(gameOverDiv); this.initGame(); }); // 清除鬼的移动定时器 if (this.ghostMoveTimer) { clearInterval(this.ghostMoveTimer); } } // 设置事件监听器 setupEventListeners() { // 键盘控制 document.addEventListener('keydown', (event) => { // 阻止方向键和WASD键的默认行为(防止页面滚动) if(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'w', 'a', 's', 'd', ' '].includes(event.key)) { event.preventDefault(); } switch(event.key) { case 'ArrowUp': case 'w': this.movePlayer(0, -1); break; case 'ArrowRight': case 'd': this.movePlayer(1, 0); break; case 'ArrowDown': case 's': this.movePlayer(0, 1); break; case 'ArrowLeft': case 'a': this.movePlayer(-1, 0); break; case ' ': this.performAction(); break; } }); // 按钮控制 document.getElementById('up').addEventListener('click', () => this.movePlayer(0, -1)); document.getElementById('right').addEventListener('click', () => this.movePlayer(1, 0)); document.getElementById('down').addEventListener('click', () => this.movePlayer(0, 1)); document.getElementById('left').addEventListener('click', () => this.movePlayer(-1, 0)); document.getElementById('action').addEventListener('click', () => this.performAction()); document.getElementById('start').addEventListener('click', () => this.initGame()); } // 设置鬼的自动移动定时器 setupGhostTimer() { // 增加间隔到400毫秒,给玩家更多反应时间 const interval = 400; this.ghostMoveTimer = setInterval(() => { if (this.gameOver) { clearInterval(this.ghostMoveTimer); return; } // 移动鬼 this.moveGhosts(); // 检查是否被鬼抓到 this.checkGhostCollision(); // 更新迷宫显示 this.renderMaze(); }, interval); } } // 游戏初始化 document.addEventListener('DOMContentLoaded', () => { const game = new BoxEscapeGame(); game.initGame(); }); </script> </body> </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2017-03-05 Java 集合的简单实现 (ArrayList & LinkedList & Queue & Stack)