基于DOM的2D网页游戏元素碰撞检测函数实现求助
Hey there! I see you're working on a DOM-based JavaScript game and stuck on collision detection—let's get this sorted out for you. First, let's fix a small typo in your existing code that might be breaking your upward movement: in your KeyPressed function, the up arrow case uses bj_top instead of obj_top—that's a simple slip-up that would stop the up arrow from working correctly.
// Wrong line: case 38: bj_top -= steps; break; // Should be: case 38: obj_top -= steps; break;
Now, let's tackle collision detection. The core idea is to check if two elements' bounding boxes overlap. We can use the getBoundingClientRect() method, which gives us an element's position (relative to the viewport) and dimensions (width, height, top, left, right, bottom)—perfect for collision checks.
Step 1: Create a Reusable Collision Detection Function
Here's a function that takes two DOM elements and returns true if they're colliding:
function checkCollision(element1, element2) { // Get bounding rectangles for both elements const rect1 = element1.getBoundingClientRect(); const rect2 = element2.getBoundingClientRect(); // Check if the rectangles overlap return !( rect1.top > rect2.bottom || rect1.bottom < rect2.top || rect1.left > rect2.right || rect1.right < rect2.left ); }
Let me break this down:
- We grab the bounding rects for both elements first.
- The
!()reverses the condition: if none of the "no collision" scenarios are true, the elements are colliding. - The "no collision" scenarios are:
- Element 1 is completely above Element 2
- Element 1 is completely below Element 2
- Element 1 is completely to the right of Element 2
- Element 1 is completely to the left of Element 2
Step 2: Use the Function in Your Game
Now let's integrate this into your existing code. You can check for collisions in places where elements move—like the monster's movement loop, or after your character moves.
Example 1: Check Collision When Monster Moves
Update your monster1Bewegen function to check for collision each time the monster moves:
function monster1Bewegen() { if(x>=810 && x<=900){ if(left) x--; else x++; } if(x == 810 || x == 900) { left = !left; } document.getElementById('monster1').style.left = x + "px"; // Get references to your character and monster1 const character = document.form01.character01; const monster1 = document.getElementById('monster1'); // Check for collision if (checkCollision(character, monster1)) { console.log("Collision detected with monster1!"); // Add your collision logic here (e.g., reduce health) const progressBar = document.getElementById('p'); progressBar.value = Math.max(0, progressBar.value - 10); } window.setTimeout(monster1Bewegen, 30); }
Example 2: Check Collision After Character Moves
You can also add the check to your setPos function, so every time the character moves, you check for collisions with all monsters:
function setPos(otop,oleft) { document.form01.character01.style.position = "absolute"; document.form01.character01.style.zIndex = "3"; document.form01.character01.style.top = otop + "px"; document.form01.character01.style.left = oleft + "px"; // Check collisions after moving the character const character = document.form01.character01; const monsters = [ document.getElementById('monster1'), document.getElementById('monster2'), document.getElementById('monster3') ]; monsters.forEach(monster => { if (checkCollision(character, monster)) { console.log(`Collision with ${monster.id}!`); // Handle collision (e.g., reduce health) const progressBar = document.getElementById('p'); progressBar.value = Math.max(0, progressBar.value - 10); } }); }
Quick Notes for Your Game
- Make sure all elements you're checking (character, monsters) have
position: absoluteorposition: relativeset—getBoundingClientRect()works with any positioning, but absolute is what you're using for the character, so that's good to go. - If you add scrolling backgrounds later, you might need to adjust for scroll position, but your current fixed viewport setup works perfectly with this function.
- You can tweak the collision logic to handle specific cases (like only counting collisions when the character lands on a monster) by adding extra checks to the condition.
I hope this gets your collision detection working smoothly! Let me know if you need further tweaks.
内容的提问来源于stack exchange,提问作者user9207992

