js实现自动寻找迷宫出口动画效果代码
代码语言:html
所属分类:动画
代码描述:js实现自动寻找迷宫出口动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> @import url(https://fonts.googleapis.com/css?family=VT323); body { margin: 0; overflow: hidden; font-family: "VT323"; display: flex; align-items: center; justify-content: center; height: 100vh; background: black; flex-direction: column; } #container { display: grid; color: #0f0; flex: 1; width: 100%; } .controls { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; } #audioFileInput { opacity: 0; position: absolute; z-index: -1; } label[for="audioFileInput"], label[for="loadWeightsInput"], button { padding: 10px 20px; background-color: black; color: white; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; margin: 0; font-family: "VT323"; } label[for="audioFileInput"]:hover, label[for="loadWeightsInput"]:hover, button:hover { color: #0f0; } #debugPanel { position: absolute; top: 10px; right: 10px; width: max-content; background: rgba(0, 0, 0, 0.1); color: #0f0; border-radius: 10px; padding: 10px; display: none; backdrop-filter: blur(5px); overflow-y: auto; max-height: 90vh; p { margin: 2px; } } #debugInfo { display: flex; flex-direction: column; } .agentType { margin-bottom: 10px; } .agentType p { margin: 2px 0; } .barContainer { display: flex; flex-direction: column; margin-top: 5px; } .barChart { width: 100%; height: 20px; background: transparent; border-radius: 5px; overflow: hidden; margin-bottom: 5px; } .bar { height: 100%; } .predator-text p { color: #FF4000; } .prey-text p { color: #00BFFF; } .normal-text p { color: #4F4F4F; } .super-predator-text p { color: #FF1493; } .scavenger-text p { color: #8B4513; } .explorer-text p { color: #32CD32; } .builder-text p { color: #FFD700; } .healer-text p { color: #EE82EE; } .predator .bar { background: #FF4000; } .prey .bar { background: #00BFFF; } .normal .bar { background: #4F4F4F; } .super-predator .bar { background: #FF1493; } .scavenger .bar { background: #8B4513; } .explorer .bar { background: #32CD32; } .builder .bar { background: #FFD700; } .healer .bar { background: #EE82EE; } #container div { transition: color 0.5s ease, font-size 0.5s ease; } </style> </head> <body translate="no"> <div id="container"></div> <div class="controls"> <input type="file" id="audioFileInput" accept="audio/*" /> <label for="audioFileInput">Select Audio</label> <button id="resetButton">Reset Simulation</button> <button id="saveWeightsButton">Save Weights</button> <input type="file" id="loadWeightsInput" style="display: none;" /> <label for="loadWeightsInput">Load Weights</label> <button id="toggleDebugButton">Toggle Debug</button> </div> <div id="debugPanel"> <div id="debugInfo"></div> </div> <script > let maze = []; let cols, rows; const charSize = 25; // Smaller size for more detailed maze let agents = []; const populationSize = 80; const mutationRate = 0.1; const maxSteps = 1000; // Maximum number of steps before resetting let generation = 0; const container = document.getElementById("container"); // Define rewards and penalties const rewardGoal = 10; // Reward for reaching the goal const penaltyStep = -0.1; // Penalty for each step taken const penaltyWall = -1; // Penalty for hitting a wall const penaltyBacktrack = -0.5; // Penalty for backtracking let goalX, goalY; // Define goal coordinates class MazeCell { constructor(x, y) { this.x = x; this.y = y; this.walls = [true, true, true, true]; // Top, right, bottom, left this.visited = false; }} function setup() { container.innerHTML = ""; const width = window.innerWidth; const height = window.innerHeight; cols = Math.floor(width / charSize); rows = Math.floor(height / charSize); container.style.gridTemplateColumns = `repeat(${cols}, ${charSize}px)`; container.style.gridTemplateRows = `repeat(${rows}, ${charSize}px)`; maze = []; for (let y = 0; y < rows; y++) { for (let x = 0; x < cols; x++) { maze.push(new MazeCell(x, y)); } } generateMaze(); initializeAgents(); // Set goal coordinates goalX = cols - 1; goalY = rows - 1; } function generateMaze() { const stack = []; const start = maze[0]; start.visited = true; stack.push(start); while (stack.length > 0) { const current = stack[stack.length - 1]; const next = getUnvisitedNeighbor(current); if (next) { next.visited = true; stack.push(next); removeWalls(current, next); // Randomly remove additional walls to make the maze easier if (Math.random() < 0.7) {// 70% chance to remove a random wall const additionalNext = getRandomNeighbor(current); if (additionalNext && additionalNext.visited) { removeWalls(current, additionalNext); } } } else { stack.pop(); } } renderMaze(); } function getUnvisitedNeighbor(cell) { const neighbors = []; const top = maze[index(cell.x, cell.y - 1)]; const right = maze[index(cell.x + 1, cell.y)]; const bottom = maze[index(cell.x, cell.y + 1)]; const left = maze[index(cell.x - 1, cell.y)]; if (top && !top.visited) neighbors.push(top); if (right && !right.visited) neighbors.push(right); if (bottom && !bottom.visited) neighbors.push(bottom); if (left && !left.visited) neighbors.push(left); if (neighbors.length > 0) { const randomIndex = Math.floor(Math.random() * neighbors.length); return neighbors[randomIndex]; } return undefined; } function getRandomNeighbor(cell) { const neighbors = []; const top = maze[index(cell.x, cell.y - 1)]; const right = maze[index(cell.x + 1, cell.y)]; const bottom = maze[index(cell.x, cell.y + 1)]; const left = maze[index(cell.x - 1, cell.y)]; if (top) neighbors.push(top); if (right) neighbors.push(right); if (bottom) neighbors.push(bottom); if (left) neighbors.push(left); if (neighbors.length > 0) { const randomIndex = Math.floor(Math.random() * neighbors.length); return neighbors[randomIndex]; } return undefined; } function index(x, y) { if (x < 0 || y < 0 || x >= cols || y >= rows) { return -1; } return x + y * cols; } function removeWalls(a, b) { const x = a.x - b.x; if (x === 1) { a.walls[3] = false; b.walls[1] = false; } else if (x === -1) { a.wa.........完整代码请登录后点击上方下载按钮下载查看
网友评论0