基于JavaScript的碰撞检测问题求助——俯视角墓地游戏开发
Hey there! Let's tackle that collision detection bug in your graveyard game—nothing kills the spooky vibe like getting stuck on a tombstone when trying to turn around. Let's break down what's going wrong and fix it step by step.
What's Causing the Stuck Issue?
Your current collision check is detecting any overlap between the character and tombstone, regardless of movement direction. When you turn around, the character might still be slightly overlapping with the tombstone, so the game thinks you're still colliding and blocks movement entirely.
Instead, we need to check if the character's next move will cause a collision, not if they're already overlapping. This prevents the "stuck" feeling because we stop movement before the character clips into the tombstone.
Revised Collision Detection Logic
Here's how to adjust your collision function to check based on movement direction:
function collision($el, $charEl, position) { const elRect = $el[0].getBoundingClientRect(); const charRect = $charEl[0].getBoundingClientRect(); // Define how much the character moves each step (adjust this to match your walking speed!) const stepSize = 10; // Calculate where the character WILL be after this step, based on direction let nextCharRect = { top: charRect.top, bottom: charRect.bottom, left: charRect.left, right: charRect.right }; switch(position) { case 0: // Up nextCharRect.top -= stepSize; nextCharRect.bottom -= stepSize; break; case 1: // Down nextCharRect.top += stepSize; nextCharRect.bottom += stepSize; break; case 2: // Left nextCharRect.left -= stepSize; nextCharRect.right -= stepSize; break; case 3: // Right nextCharRect.left += stepSize; nextCharRect.right += stepSize; break; } // Check if the next position overlaps with the tombstone const noOverlap = nextCharRect.bottom < elRect.top || nextCharRect.top > elRect.bottom || nextCharRect.right < elRect.left || nextCharRect.left > elRect.right; // If there IS overlap, return true (collision detected) return !noOverlap; }
Adjusting the Walking Function
We also need to make sure we reset the collision flag correctly each time we check for collisions. Here's the updated walking function:
function walking() { let hasCollision = false; $stones.each(function() { if (collision($(this), $char, position)) { hasCollision = true; return false; // Break out of the loop early } }); if (!hasCollision) { // Only move if no collision is detected const stepSize = 10; // Match this to the stepSize in collision() switch(position) { case 0: // Up $char.css('top', parseInt($char.css('top')) - stepSize + 'px'); break; case 1: // Down $char.css('top', parseInt($char.css('top')) + stepSize + 'px'); break; case 2: // Left $char.css('left', parseInt($char.css('left')) - stepSize + 'px'); break; case 3: // Right $char.css('left', parseInt($char.css('left')) + stepSize + 'px'); break; } } }
Key Fixes Explained
- Predictive Collision Check: We calculate where the character will be after moving, not where they are now. This stops movement before the character clips into the tombstone.
- Direction-Specific Checks: The collision logic only cares about the direction the character is moving, so turning around won't trigger a collision unless the new direction would take them into a tombstone.
- Proper Flag Reset: We use a local
hasCollisionvariable instead of the globalcollisionvariable, which ensures we start fresh each time thewalkingfunction runs.
Small Tweaks to Avoid Sticking
- Make sure
stepSizematches in both thecollisionandwalkingfunctions—this keeps your prediction accurate. - If you're using CSS positioning (like
top/left), ensure your character and tombstones are using the same positioning scheme (e.g.,position: absolute).
Give this a try—your character should now stop neatly at tombstones and be able to turn around without getting stuck!
内容的提问来源于stack exchange,提问作者Kenton de Jong

