2D迷宫游戏基于可行走区域坐标的移动限制实现求助
Hey there! Let's figure out why your allowed path logic isn't working and get it fixed up properly.
First, let's break down the issues in your current code:
- You're only checking individual X/Y coordinates, not their combination: A maze's walkable area depends on both X and Y together—for example, a certain Y value might have some X positions that are allowed and others that aren't. Checking just
allowedPathYdoesn't account for that. - You're validating the current position, not the new one: Your code checks if the player's current Y is in the allowed list before moving, but it doesn't verify where they'll end up after moving. That means they could still walk into a wall if the new position isn't allowed.
- Only the upward movement has (broken) logic: Your down/left/right movements don't have any allowed path checks at all, so those directions let the player move freely regardless of the maze.
Fixing the Logic
The core idea of using a walkable coordinate list is solid—here's how to implement it correctly:
1. Store Walkable Positions as Coordinate Pairs
Instead of separate allowedPathX and allowedPathY arrays, use an array of objects that hold both X and Y for each walkable spot. For example:
// Example: Replace with your actual walkable coordinates from map drawing const allowedPaths = [ { x: 50, y: 50 }, { x: 50, y: 100 }, { x: 100, y: 50 }, // Add all your walkable positions here ];
2. Add a Helper Function to Validate Positions
Create a reusable function to check if a given (X,Y) position is in the allowed list. If your movement uses continuous coordinates (not grid-aligned), you might need to adjust this to check if the position falls within a walkable area, but for grid-based movement, this works:
function isPositionAllowed(targetX, targetY) { // If your coordinates are pixel-perfect, use exact matches return allowedPaths.some(pos => pos.x === targetX && pos.y === targetY); // If you're using grid movement with variable speed, you might round coordinates first: // const roundedX = Math.round(targetX / gridSize) * gridSize; // const roundedY = Math.round(targetY / gridSize) * gridSize; // return allowedPaths.some(pos => pos.x === roundedX && pos.y === roundedY); }
3. Update the Game Loop to Check New Positions
Modify your game loop to calculate the player's intended new position first, validate it, and only update the player's position if it's allowed:
function gameLoop() { ctxPc.clearRect(0, 0, pcCanvas.width, pcCanvas.height); // Calculate the player's intended new position let newPositionX = positionX; let newPositionY = positionY; if (playerUp) { newPositionY -= moveSpeed; } else if (playerDown) { newPositionY += moveSpeed; } if (playerLeft) { newPositionX -= moveSpeed; } else if (playerRight) { newPositionX += moveSpeed; } // Only update position if the new spot is allowed if (isPositionAllowed(newPositionX, newPositionY)) { positionX = newPositionX; positionY = newPositionY; } drawPlayer(positionX, positionY); window.requestAnimationFrame(gameLoop); console.log(positionX, positionY); } gameLoop();
Key Notes
- When building your
allowedPathsarray during map drawing, make sure you're adding every valid walkable position. For example, if you're drawing a grid, each empty cell's coordinates should go into this array. - If your movement is smooth (not grid-locked), you might need to adjust the validation to check if the player's next position is within any walkable rectangle instead of exact coordinate matches. For example, you could store walkable areas as
{x1, y1, x2, y2}and check if the new position is inside any of those rectangles.
This approach will properly restrict the player to only the allowed areas of your maze—much better than the partial logic you had before!
内容的提问来源于stack exchange,提问作者Peter S

