jQuery移动元素碰撞检测与路径规避方案咨询
Got it, let's work through how to add collision avoidance to your random-moving dots. Your current code makes each dot animate straight to a random target without checking for other dots—so collisions are inevitable. The jQuery Collision plugin is a great tool here, and I'll show you exactly how to integrate it into your animation flow.
First, Let's Recap the Problem
Your existing code generates random positions and animates each dot independently. No collision checks mean dots can overlap completely as they move. We need to add collision detection during the animation and adjust the dots' paths when a collision is detected.
Step 1: Ensure the Collision Plugin is Loaded
First, make sure you've included the jQuery Collision plugin after jQuery itself. For example:
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="jquery.collision.min.js"></script> <!-- Use your actual plugin file path -->
Step 2: Modify the Animation Function with Collision Checks
We'll update your animateDiv function to use jQuery's animate() step callback—this lets us run code every frame of the animation, which is perfect for real-time collision detection. Here's the revised code:
function runGame(parameter) { document.getElementById("blocks").style.display = "block"; document.getElementById('start-button').style.display = 'none'; let divs = document.getElementsByClassName("block"); for (let div of divs) { // Fixed: use for...of instead of for...in to avoid iterating over prototype properties animateDiv(div); } }; function makeNewPosition() { var height = $(window).height() - 50; var width = $(window).width() - 50; var newh = Math.floor(Math.random() * height); var neww = Math.floor(Math.random() * width); return [newh, neww]; } function animateDiv(myElement) { var newq = makeNewPosition(); var $currentDot = $(myElement); $currentDot.animate( { top: newq[0], left: newq[1] }, { duration: 3000, step: function(now, fx) { // Detect collisions with all other dots (exclude the current one) var $otherDots = $(".block").not($currentDot); var collidingDots = $currentDot.collision($otherDots); if (collidingDots.length > 0) { // If we hit another dot, calculate an avoidance direction let $collidingDot = $(collidingDots[0]); let currentPos = $currentDot.position(); let colliderPos = $collidingDot.position(); // Move away from the colliding dot (simple directional adjustment) let newTop = currentPos.top + (currentPos.top > colliderPos.top ? 6 : -6); let newLeft = currentPos.left + (currentPos.left > colliderPos.left ? 6 : -6); // Keep the dot within window bounds newTop = Math.max(0, Math.min(newTop, $(window).height() - 50)); newLeft = Math.max(0, Math.min(newLeft, $(window).width() - 50)); // Stop the current animation, update position, and restart toward the target $currentDot.stop().css({ top: newTop, left: newLeft }); animateDiv(myElement); } }, complete: function() { // Once we reach the target, start a new animation animateDiv(myElement); } } ); }
Key Changes Explained:
- Fixed the loop: Swapped
for...inwithfor...ofinrunGameto avoid iterating over non-element properties of the HTMLCollection. - Step callback: The
stepfunction runs on every frame of the animation. Here we check if the current dot is colliding with any others using$currentDot.collision($otherDots). - Collision avoidance: When a collision is detected, we calculate a direction to move away from the colliding dot, adjust the current dot's position, stop the current animation, and restart it toward the original target.
- Boundary checks: We make sure the dot doesn't move outside the window after adjusting position.
Optional Improvements for Smoother Behavior
- Better avoidance logic: Instead of a simple +/-6 adjustment, calculate a perpendicular vector to the colliding dot for more natural movement.
- Pre-check target positions: Before animating to a new random position, check if it's too close to other dots to reduce initial collisions.
- Throttle collision checks: For large numbers of dots, only check collisions with dots in a nearby area to reduce computational load.
内容的提问来源于stack exchange,提问作者Dominik Bayer

