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>
复制代码

 

posted @   我不吃饼干呀  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2017-03-05 Java 集合的简单实现 (ArrayList & LinkedList & Queue & Stack)
点击右上角即可分享
微信分享提示