"迷宫逃脱"听上去就像一部小型解谜电影:玩家被困在一座充满陷阱的迷宫里,要一边找出口,一边小心避开敌人 。 如果是从零开始开发,麻烦就大了------随机迷宫生成算法、角色移动逻辑、敌人巡逻 AI、出口判定、碰撞检测,每个环节都够写一整天。
但现在,有了 Trae IDE,你只要一句话,游戏立刻就能跑起来。
💡 我想要的迷宫体验
脑子里构想的玩法很直接:
- 迷宫要随机:每一局都不一样,才有探索的感觉。
- 有敌人巡逻:玩家不只是找路,还要小心不被敌人"抓"到。
- 有出口目标:必须找到隐藏的出口才算胜利。
- 带点谜题:比如开门要找到钥匙,或者触发机关。
于是我在 Trae 输入了一句话:
"生成一个迷宫逃脱游戏,玩家需要在迷宫中找到出口,避免碰到敌人。"

✨ Trae 怎么实现
几秒钟后,Trae 自动给出了一款完整的 **"迷宫逃脱"**:
✅ 随机迷宫生成 :每一局布局不同,探索感直接拉满。 ✅ 玩家移动流畅 :上下左右移动不卡顿,还能支持键盘或手指触控。 ✅ 敌人巡逻 AI :敌人会自动在迷宫里巡逻,被碰到就 Game Over。 ✅ 出口机制 :找到出口时,自动弹出"胜利"提示。 ✅ 额外彩蛋:Trae 还顺带加了钥匙和小谜题,比如要先找到钥匙才能开出口门。

🧩 试玩感受
试玩时我真的有点上头:
🌀 第一眼看到迷宫 ,每条路都像能通,结果走了个死胡同; ⚠ 敌人突然拐角出现 ,吓得我赶紧往回跑; 🎯 终于摸到出口 ,那一瞬间特别解压,想立刻开下一局看看新迷宫长啥样。
Trae 自动生成的不只是"能玩",而且很有探索和挑战的感觉。

🛠 想加点料?一句话搞定
Trae 的好处是,随时能扩展玩法,比如:
- "加一个计时模式" → 限时逃脱,时间到了就失败。
- "让敌人会追击" → 被看到后敌人会加速追你,刺激感更强。
- "加入陷阱格子" → 不小心踩到会被减速或传送回起点。
- "加个迷宫难度选择" → 玩家可以挑简单、中等、地狱模式。
这些改动一句描述就能实现,完全不需要自己去写复杂逻辑。
🎮 以前 VS 现在
过去写迷宫游戏:
- 设计 迷宫生成算法;
- 写 敌人 AI;
- 调 碰撞检测;
- 做 出口机制与谜题逻辑。
每一环都耗时又容易出 bug。
现在用 Trae: 👉 一句话生成核心玩法; 👉 想改什么就再说一句,马上补全逻辑。
开发效率从"熬夜写代码"变成"轻松说想法"。
✅ 结语
如果你也想做一款 "随机迷宫+逃脱挑战" 的小游戏,打开 Trae,只要输入:
"生成一个迷宫逃脱游戏,玩家需要在迷宫中找到出口,避免碰到敌人。"
几秒后,你就能玩到一款真正能让你又烧脑又上头的迷宫逃脱游戏------每一局地图都不一样,敌人还在巡逻,探索感十足。
这就是 Trae 的魅力 ------ 让开发变成创意释放,让玩家变成第一批体验你想法的人。
html
<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: #222;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
color: #fff;
}
.game-container {
position: relative;
width: 800px;
height: 600px;
background-color: #000;
border: 2px solid #444;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 255, 0, 0.3);
overflow: hidden;
}
.maze {
position: absolute;
top: 50px;
left: 50px;
width: 700px;
height: 500px;
}
.wall {
position: absolute;
background-color: #333;
border: 1px solid #444;
}
.player {
position: absolute;
width: 20px;
height: 20px;
background-color: #0f0;
border-radius: 50%;
box-shadow: 0 0 10px #0f0;
z-index: 10;
transition: transform 0.1s;
}
.enemy {
position: absolute;
width: 20px;
height: 20px;
background-color: #f00;
border-radius: 50%;
box-shadow: 0 0 10px #f00;
z-index: 5;
}
.exit {
position: absolute;
width: 30px;
height: 30px;
background-color: #00f;
border-radius: 5px;
box-shadow: 0 0 15px #00f;
z-index: 3;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 15px #00f; }
50% { box-shadow: 0 0 25px #00f; }
100% { box-shadow: 0 0 15px #00f; }
}
.score-container {
position: absolute;
top: 10px;
left: 10px;
font-size: 18px;
color: #fff;
z-index: 20;
}
.level-container {
position: absolute;
top: 10px;
right: 10px;
font-size: 18px;
color: #fff;
z-index: 20;
}
.timer-container {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
font-size: 18px;
color: #fff;
z-index: 20;
}
.game-over {
position: absolute;
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: 30;
display: none;
}
.game-over-title {
font-size: 48px;
font-weight: bold;
color: #f00;
margin-bottom: 20px;
text-shadow: 0 0 10px #f00;
}
.final-score {
font-size: 24px;
color: #fff;
margin-bottom: 10px;
text-shadow: 0 0 5px #fff;
}
.final-time {
font-size: 24px;
color: #fff;
margin-bottom: 30px;
text-shadow: 0 0 5px #fff;
}
.restart-button {
padding: 15px 30px;
font-size: 20px;
background-color: #0f0;
color: #000;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
.restart-button:hover {
background-color: #0c0;
transform: scale(1.05);
box-shadow: 0 0 10px #0f0;
}
.level-complete {
position: absolute;
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: 30;
display: none;
}
.level-complete-title {
font-size: 48px;
font-weight: bold;
color: #0f0;
margin-bottom: 20px;
text-shadow: 0 0 10px #0f0;
}
.level-stats {
font-size: 24px;
color: #fff;
margin-bottom: 10px;
text-shadow: 0 0 5px #fff;
}
.next-level-button {
padding: 15px 30px;
font-size: 20px;
background-color: #0f0;
color: #000;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
margin-top: 20px;
}
.next-level-button:hover {
background-color: #0c0;
transform: scale(1.05);
box-shadow: 0 0 10px #0f0;
}
.start-screen {
position: absolute;
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: 30;
}
.start-title {
font-size: 48px;
font-weight: bold;
color: #0f0;
margin-bottom: 20px;
text-shadow: 0 0 10px #0f0;
}
.start-instructions {
font-size: 18px;
color: #fff;
margin-bottom: 30px;
text-align: center;
max-width: 80%;
line-height: 1.5;
}
.start-button {
padding: 15px 30px;
font-size: 20px;
background-color: #0f0;
color: #000;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
.start-button:hover {
background-color: #0c0;
transform: scale(1.05);
box-shadow: 0 0 10px #0f0;
}
.fog-of-war {
position: absolute;
background-color: rgba(0, 0, 0, 0.9);
z-index: 4;
transition: opacity 0.5s;
}
.key {
position: absolute;
width: 20px;
height: 20px;
background-color: #ff0;
border-radius: 50%;
box-shadow: 0 0 10px #ff0;
z-index: 3;
animation: keyPulse 1.5s infinite;
}
@keyframes keyPulse {
0% { box-shadow: 0 0 10px #ff0; }
50% { box-shadow: 0 0 20px #ff0; }
100% { box-shadow: 0 0 10px #ff0; }
}
</style>
</head>
<body>
<div class="game-container" id="game-container">
<div class="score-container">
分数: <span id="score">0</span>
</div>
<div class="level-container">
关卡: <span id="level">1</span>
</div>
<div class="timer-container">
时间: <span id="timer">0</span>
</div>
<div class="maze" id="maze"></div>
<div class="game-over" id="game-over">
<div class="game-over-title">游戏结束</div>
<div class="final-score">最终分数: <span id="final-score">0</span></div>
<div class="final-time">总用时: <span id="final-time">0</span></div>
<button class="restart-button" id="restart-button">再玩一次</button>
</div>
<div class="level-complete" id="level-complete">
<div class="level-complete-title">关卡完成!</div>
<div class="level-stats">关卡分数: <span id="level-score">0</span></div>
<div class="level-stats">关卡用时: <span id="level-time">0</span></div>
<button class="next-level-button" id="next-level-button">下一关</button>
</div>
<div class="start-screen" id="start-screen">
<div class="start-title">迷宫逃脱</div>
<div class="start-instructions">
使用方向键或WASD移动玩家,找到蓝色出口逃离迷宫。<br>
避开红色敌人,收集黄色钥匙获得额外分数。<br>
每一关的迷宫都会变得更加复杂,敌人也会变得更多更快。<br>
祝你好运!
</div>
<button class="start-button" id="start-button">开始游戏</button>
</div>
</div>
<script>
// 游戏元素
const gameContainer = document.getElementById('game-container');
const mazeElement = document.getElementById('maze');
const scoreElement = document.getElementById('score');
const levelElement = document.getElementById('level');
const timerElement = document.getElementById('timer');
const gameOverElement = document.getElementById('game-over');
const finalScoreElement = document.getElementById('final-score');
const finalTimeElement = document.getElementById('final-time');
const restartButton = document.getElementById('restart-button');
const levelCompleteElement = document.getElementById('level-complete');
const levelScoreElement = document.getElementById('level-score');
const levelTimeElement = document.getElementById('level-time');
const nextLevelButton = document.getElementById('next-level-button');
const startScreen = document.getElementById('start-screen');
const startButton = document.getElementById('start-button');
// 游戏配置
const mazeWidth = 700;
const mazeHeight = 500;
const cellSize = 25; // 迷宫单元格大小
const cols = Math.floor(mazeWidth / cellSize);
const rows = Math.floor(mazeHeight / cellSize);
const playerSize = 20;
const enemySize = 20;
const exitSize = 30;
const keySize = 20;
const playerSpeed = 5;
const fogRadius = 100; // 视野半径
// 游戏状态
let maze = [];
let walls = [];
let player = null;
let enemies = [];
let exit = null;
let keys = [];
let fogElements = [];
let score = 0;
let level = 1;
let timer = 0;
let gameRunning = false;
let gameLoop;
let timerInterval;
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
let keysCollected = 0;
// 初始化游戏
function initGame() {
// 隐藏开始屏幕
startScreen.style.display = 'none';
// 重置游戏状态
resetGame();
// 生成迷宫
generateMaze();
// 放置玩家、出口和敌人
placeGameElements();
// 创建迷雾
createFogOfWar();
// 更新显示
updateDisplay();
// 开始游戏循环
gameRunning = true;
gameLoop = setInterval(updateGame, 16); // 约60帧每秒
// 开始计时器
timerInterval = setInterval(() => {
if (gameRunning) {
timer++;
timerElement.textContent = formatTime(timer);
}
}, 1000);
}
// 重置游戏状态
function resetGame() {
// 清除迷宫元素
mazeElement.innerHTML = '';
// 重置游戏状态
maze = [];
walls = [];
player = null;
enemies = [];
exit = null;
keys = [];
fogElements = [];
if (level === 1) {
score = 0;
timer = 0;
}
// 更新显示
scoreElement.textContent = score;
levelElement.textContent = level;
timerElement.textContent = formatTime(timer);
// 清除定时器
if (gameLoop) clearInterval(gameLoop);
if (timerInterval) clearInterval(timerInterval);
}
// 格式化时间
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = seconds % 60;
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
// 生成迷宫 (使用深度优先搜索算法)
function generateMaze() {
// 初始化迷宫网格
for (let y = 0; y < rows; y++) {
maze[y] = [];
for (let x = 0; x < cols; x++) {
maze[y][x] = {
x: x,
y: y,
walls: {
top: true,
right: true,
bottom: true,
left: true
},
visited: false
};
}
}
// 从随机位置开始
const startX = Math.floor(Math.random() * cols);
const startY = Math.floor(Math.random() * rows);
const stack = [];
let current = maze[startY][startX];
current.visited = true;
// 深度优先搜索生成迷宫
do {
const neighbors = getUnvisitedNeighbors(current);
if (neighbors.length > 0) {
// 随机选择一个未访问的邻居
const next = neighbors[Math.floor(Math.random() * neighbors.length)];
stack.push(current);
// 移除两个单元格之间的墙
removeWalls(current, next);
// 移动到下一个单元格
current = next;
current.visited = true;
} else if (stack.length > 0) {
// 回溯
current = stack.pop();
}
} while (stack.length > 0);
// 根据难度增加额外的通道 (使迷宫更简单或更复杂)
const extraPathsCount = Math.max(1, Math.floor(cols * rows * (0.1 - level * 0.01)));
for (let i = 0; i < extraPathsCount; i++) {
const x = Math.floor(Math.random() * (cols - 1));
const y = Math.floor(Math.random() * (rows - 1));
if (Math.random() < 0.5) {
// 移除水平墙
maze[y][x].walls.bottom = false;
maze[y + 1][x].walls.top = false;
} else {
// 移除垂直墙
maze[y][x].walls.right = false;
maze[y][x + 1].walls.left = false;
}
}
// 创建墙壁元素
createWalls();
}
// 获取未访问的邻居
function getUnvisitedNeighbors(cell) {
const neighbors = [];
const {x, y} = cell;
// 上
if (y > 0 && !maze[y - 1][x].visited) {
neighbors.push(maze[y - 1][x]);
}
// 右
if (x < cols - 1 && !maze[y][x + 1].visited) {
neighbors.push(maze[y][x + 1]);
}
// 下
if (y < rows - 1 && !maze[y + 1][x].visited) {
neighbors.push(maze[y + 1][x]);
}
// 左
if (x > 0 && !maze[y][x - 1].visited) {
neighbors.push(maze[y][x - 1]);
}
return neighbors;
}
// 移除两个单元格之间的墙
function removeWalls(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
if (dx === 1) {
a.walls.left = false;
b.walls.right = false;
} else if (dx === -1) {
a.walls.right = false;
b.walls.left = false;
}
if (dy === 1) {
a.walls.top = false;
b.walls.bottom = false;
} else if (dy === -1) {
a.walls.bottom = false;
b.walls.top = false;
}
}
// 创建墙壁元素
function createWalls() {
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const cell = maze[y][x];
const cellX = x * cellSize;
const cellY = y * cellSize;
// 创建墙壁
if (cell.walls.top) {
createWall(cellX, cellY, cellSize, 2);
}
if (cell.walls.right) {
createWall(cellX + cellSize - 2, cellY, 2, cellSize);
}
if (cell.walls.bottom) {
createWall(cellX, cellY + cellSize - 2, cellSize, 2);
}
if (cell.walls.left) {
createWall(cellX, cellY, 2, cellSize);
}
}
}
// 添加外墙
createWall(-2, -2, mazeWidth + 4, 2); // 上
createWall(mazeWidth, -2, 2, mazeHeight + 4); // 右
createWall(-2, mazeHeight, mazeWidth + 4, 2); // 下
createWall(-2, -2, 2, mazeHeight + 4); // 左
}
// 创建单个墙壁
function createWall(x, y, width, height) {
const wall = document.createElement('div');
wall.className = 'wall';
wall.style.left = `${x + 50}px`; // 50是迷宫的左边距
wall.style.top = `${y + 50}px`; // 50是迷宫的上边距
wall.style.width = `${width}px`;
wall.style.height = `${height}px`;
mazeElement.appendChild(wall);
walls.push({
element: wall,
x: x + 50,
y: y + 50,
width: width,
height: height
});
}
// 放置游戏元素
function placeGameElements() {
// 找到可用的单元格 (没有墙的地方)
const availableCells = [];
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
availableCells.push({x, y});
}
}
// 随机打乱单元格
shuffleArray(availableCells);
// 放置玩家 (在左上角区域)
const playerCell = availableCells.find(cell => cell.x < cols / 3 && cell.y < rows / 3);
createPlayer(playerCell.x * cellSize + (cellSize - playerSize) / 2 + 50,
playerCell.y * cellSize + (cellSize - playerSize) / 2 + 50);
// 放置出口 (在右下角区域)
const exitCell = availableCells.find(cell =>
cell.x > cols * 2/3 && cell.y > rows * 2/3 &&
(cell.x !== playerCell.x || cell.y !== playerCell.y));
createExit(exitCell.x * cellSize + (cellSize - exitSize) / 2 + 50,
exitCell.y * cellSize + (cellSize - exitSize) / 2 + 50);
// 放置钥匙
const keyCount = Math.min(5, level + 1);
for (let i = 0; i < keyCount; i++) {
const keyCell = availableCells.find(cell =>
(cell.x !== playerCell.x || cell.y !== playerCell.y) &&
(cell.x !== exitCell.x || cell.y !== exitCell.y) &&
!keys.some(k =>
Math.floor((k.x - 50) / cellSize) === cell.x &&
Math.floor((k.y - 50) / cellSize) === cell.y
));
if (keyCell) {
createKey(keyCell.x * cellSize + (cellSize - keySize) / 2 + 50,
keyCell.y * cellSize + (cellSize - keySize) / 2 + 50);
}
}
// 放置敌人
const enemyCount = Math.min(10, level + 2);
for (let i = 0; i < enemyCount; i++) {
const enemyCell = availableCells.find(cell =>
(cell.x !== playerCell.x || cell.y !== playerCell.y) &&
(cell.x !== exitCell.x || cell.y !== exitCell.y) &&
!keys.some(k =>
Math.floor((k.x - 50) / cellSize) === cell.x &&
Math.floor((k.y - 50) / cellSize) === cell.y
) &&
!enemies.some(e =>
Math.floor((e.x - 50) / cellSize) === cell.x &&
Math.floor((e.y - 50) / cellSize) === cell.y
));
if (enemyCell) {
createEnemy(enemyCell.x * cellSize + (cellSize - enemySize) / 2 + 50,
enemyCell.y * cellSize + (cellSize - enemySize) / 2 + 50);
}
}
}
// 创建玩家
function createPlayer(x, y) {
const playerElement = document.createElement('div');
playerElement.className = 'player';
playerElement.style.left = `${x}px`;
playerElement.style.top = `${y}px`;
playerElement.style.width = `${playerSize}px`;
playerElement.style.height = `${playerSize}px`;
mazeElement.appendChild(playerElement);
player = {
element: playerElement,
x: x,
y: y,
width: playerSize,
height: playerSize
};
}
// 创建敌人
function createEnemy(x, y) {
const enemyElement = document.createElement('div');
enemyElement.className = 'enemy';
enemyElement.style.left = `${x}px`;
enemyElement.style.top = `${y}px`;
enemyElement.style.width = `${enemySize}px`;
enemyElement.style.height = `${enemySize}px`;
mazeElement.appendChild(enemyElement);
// 随机敌人速度 (根据关卡增加)
const speed = 1 + Math.random() * (level * 0.5);
enemies.push({
element: enemyElement,
x: x,
y: y,
width: enemySize,
height: enemySize,
speed: speed,
direction: Math.floor(Math.random() * 4), // 0: 上, 1: 右, 2: 下, 3: 左
moveCounter: 0,
changeDirectionCounter: 0
});
}
// 创建出口
function createExit(x, y) {
const exitElement = document.createElement('div');
exitElement.className = 'exit';
exitElement.style.left = `${x}px`;
exitElement.style.top = `${y}px`;
exitElement.style.width = `${exitSize}px`;
exitElement.style.height = `${exitSize}px`;
mazeElement.appendChild(exitElement);
exit = {
element: exitElement,
x: x,
y: y,
width: exitSize,
height: exitSize
};
}
// 创建钥匙
function createKey(x, y) {
const keyElement = document.createElement('div');
keyElement.className = 'key';
keyElement.style.left = `${x}px`;
keyElement.style.top = `${y}px`;
keyElement.style.width = `${keySize}px`;
keyElement.style.height = `${keySize}px`;
mazeElement.appendChild(keyElement);
keys.push({
element: keyElement,
x: x,
y: y,
width: keySize,
height: keySize,
collected: false
});
}
// 创建迷雾
function createFogOfWar() {
// 如果关卡大于3,添加迷雾效果
if (level > 3) {
// 创建迷雾元素覆盖整个迷宫
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const fogElement = document.createElement('div');
fogElement.className = 'fog-of-war';
fogElement.style.left = `${x * cellSize + 50}px`;
fogElement.style.top = `${y * cellSize + 50}px`;
fogElement.style.width = `${cellSize}px`;
fogElement.style.height = `${cellSize}px`;
mazeElement.appendChild(fogElement);
fogElements.push({
element: fogElement,
x: x * cellSize + 50,
y: y * cellSize + 50,
width: cellSize,
height: cellSize
});
}
}
}
}
// 更新迷雾
function updateFogOfWar() {
if (level > 3 && player) {
const playerCenterX = player.x + player.width / 2;
const playerCenterY = player.y + player.height / 2;
fogElements.forEach(fog => {
const fogCenterX = fog.x + fog.width / 2;
const fogCenterY = fog.y + fog.height / 2;
const distance = Math.sqrt(
Math.pow(playerCenterX - fogCenterX, 2) +
Math.pow(playerCenterY - fogCenterY, 2)
);
// 根据距离设置透明度
if (distance < fogRadius) {
fog.element.style.opacity = '0';
} else {
const opacity = Math.min(1, (distance - fogRadius) / 50);
fog.element.style.opacity = opacity.toString();
}
});
}
}
// 更新游戏
function updateGame() {
if (!gameRunning) return;
// 更新玩家位置
updatePlayerPosition();
// 更新敌人位置
updateEnemies();
// 检查碰撞
checkCollisions();
// 更新迷雾
updateFogOfWar();
}
// 更新玩家位置
function updatePlayerPosition() {
let newX = player.x;
let newY = player.y;
if (upPressed) {
newY -= playerSpeed;
}
if (downPressed) {
newY += playerSpeed;
}
if (leftPressed) {
newX -= playerSpeed;
}
if (rightPressed) {
newX += playerSpeed;
}
// 检查墙壁碰撞
if (!checkWallCollision(newX, newY)) {
player.x = newX;
player.y = newY;
player.element.style.left = `${newX}px`;
player.element.style.top = `${newY}px`;
}
}
// 检查墙壁碰撞
function checkWallCollision(x, y) {
for (const wall of walls) {
if (x < wall.x + wall.width &&
x + playerSize > wall.x &&
y < wall.y + wall.height &&
y + playerSize > wall.y) {
return true;
}
}
return false;
}
// 更新敌人
function updateEnemies() {
enemies.forEach(enemy => {
// 增加移动计数器
enemy.moveCounter += enemy.speed;
enemy.changeDirectionCounter++;
// 每隔一段时间随机改变方向
if (enemy.changeDirectionCounter > 100 + Math.random() * 100) {
enemy.direction = Math.floor(Math.random() * 4);
enemy.changeDirectionCounter = 0;
}
// 如果玩家靠近,有几率朝玩家方向移动
const distanceToPlayer = Math.sqrt(
Math.pow(player.x - enemy.x, 2) +
Math.pow(player.y - enemy.y, 2)
);
if (distanceToPlayer < 150 && Math.random() < 0.1) {
// 确定玩家相对于敌人的方向
if (Math.abs(player.x - enemy.x) > Math.abs(player.y - enemy.y)) {
enemy.direction = player.x > enemy.x ? 1 : 3;
} else {
enemy.direction = player.y > enemy.y ? 2 : 0;
}
}
// 只有当移动计数器达到阈值时才移动
if (enemy.moveCounter >= 1) {
let newX = enemy.x;
let newY = enemy.y;
// 根据方向移动
if (enemy.direction === 0) { // 上
newY -= 1;
} else if (enemy.direction === 1) { // 右
newX += 1;
} else if (enemy.direction === 2) { // 下
newY += 1;
} else if (enemy.direction === 3) { // 左
newX -= 1;
}
// 检查墙壁碰撞
if (!checkWallCollision(newX, newY)) {
enemy.x = newX;
enemy.y = newY;
enemy.element.style.left = `${newX}px`;
enemy.element.style.top = `${newY}px`;
} else {
// 如果碰到墙,改变方向
enemy.direction = (enemy.direction + 2) % 4; // 反向
}
enemy.moveCounter = 0;
}
});
}
// 检查碰撞
function checkCollisions() {
// 检查与敌人的碰撞
for (const enemy of enemies) {
if (checkRectCollision(player, enemy)) {
endGame();
return;
}
}
// 检查与出口的碰撞
if (checkRectCollision(player, exit)) {
completeLevel();
return;
}
// 检查与钥匙的碰撞
for (const key of keys) {
if (!key.collected && checkRectCollision(player, key)) {
collectKey(key);
}
}
}
// 检查矩形碰撞
function checkRectCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y;
}
// 收集钥匙
function collectKey(key) {
key.collected = true;
key.element.style.display = 'none';
// 增加分数
score += 100;
scoreElement.textContent = score;
// 增加已收集钥匙数量
keysCollected++;
// 如果收集了所有钥匙,增加额外分数
if (keysCollected === keys.length) {
score += 500;
scoreElement.textContent = score;
}
}
// 完成关卡
function completeLevel() {
gameRunning = false;
clearInterval(gameLoop);
// 计算关卡分数 (基础分 + 时间奖励 + 钥匙奖励)
const levelScore = 1000 + Math.max(0, 2000 - timer * 10) + keysCollected * 100;
score += levelScore;
// 更新显示
levelScoreElement.textContent = levelScore;
levelTimeElement.textContent = formatTime(timer);
scoreElement.textContent = score;
// 显示关卡完成界面
levelCompleteElement.style.display = 'flex';
}
// 游戏结束
function endGame() {
gameRunning = false;
clearInterval(gameLoop);
clearInterval(timerInterval);
// 更新显示
finalScoreElement.textContent = score;
finalTimeElement.textContent = formatTime(timer);
// 显示游戏结束界面
gameOverElement.style.display = 'flex';
}
// 下一关
function nextLevel() {
level++;
levelCompleteElement.style.display = 'none';
// 重置游戏状态并开始新关卡
resetGame();
generateMaze();
placeGameElements();
createFogOfWar();
updateDisplay();
// 开始游戏循环
gameRunning = true;
gameLoop = setInterval(updateGame, 16);
// 开始计时器
timerInterval = setInterval(() => {
if (gameRunning) {
timer++;
timerElement.textContent = formatTime(timer);
}
}, 1000);
}
// 重新开始游戏
function restartGame() {
level = 1;
gameOverElement.style.display = 'none';
// 重置游戏状态并开始新游戏
resetGame();
generateMaze();
placeGameElements();
createFogOfWar();
updateDisplay();
// 开始游戏循环
gameRunning = true;
gameLoop = setInterval(updateGame, 16);
// 开始计时器
timerInterval = setInterval(() => {
if (gameRunning) {
timer++;
timerElement.textContent = formatTime(timer);
}
}, 1000);
}
// 更新显示
function updateDisplay() {
scoreElement.textContent = score;
levelElement.textContent = level;
timerElement.textContent = formatTime(timer);
}
// 辅助函数:随机打乱数组
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// 键盘事件监听
document.addEventListener('keydown', (e) => {
if (!gameRunning) return;
if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') {
upPressed = true;
}
if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') {
downPressed = true;
}
if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') {
leftPressed = true;
}
if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') {
rightPressed = true;
}
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') {
upPressed = false;
}
if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') {
downPressed = false;
}
if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') {
leftPressed = false;
}
if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') {
rightPressed = false;
}
});
// 触摸控制 (用于移动设备)
let touchStartX = 0;
let touchStartY = 0;
gameContainer.addEventListener('touchstart', (e) => {
if (!gameRunning) return;
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
});
gameContainer.addEventListener('touchmove', (e) => {
if (!gameRunning) return;
e.preventDefault();
const touchX = e.touches[0].clientX;
const touchY = e.touches[0].clientY;
const diffX = touchX - touchStartX;
const diffY = touchY - touchStartY;
// 重置所有方向
upPressed = false;
downPressed = false;
leftPressed = false;
rightPressed = false;
// 设置新方向 (基于最大差值)
if (Math.abs(diffX) > Math.abs(diffY)) {
if (diffX > 20) {
rightPressed = true;
} else if (diffX < -20) {
leftPressed = true;
}
} else {
if (diffY > 20) {
downPressed = true;
} else if (diffY < -20) {
upPressed = true;
}
}
});
gameContainer.addEventListener('touchend', () => {
upPressed = false;
downPressed = false;
leftPressed = false;
rightPressed = false;
});
// 按钮事件监听
startButton.addEventListener('click', initGame);
restartButton.addEventListener('click', restartGame);
nextLevelButton.addEventListener('click', nextLevel);
</script>
</body>
</html>