简体   繁体   中英

Detect collision between two elements

I want to detect a collision between two divs and I've tried to do that using the offsetLeft and offsetTop of each one of the divs and by using getBoundingClientRect() . But none of these work.

Is there a way I can get the exact coordinates in which these two elements touch?

 const bigDiv = document.querySelector(".big") const blue = document.querySelector(".blue") const startBtn = document.querySelector("button") const red = document.querySelector(".red") const bigDivDimensions = bigDiv.getBoundingClientRect(); let speed = 5; //let counter = 0; let bigDivLeft = bigDivDimensions.left; startGame(); function random() { return Math.floor(Math.random() * (bigDivDimensions.width - 40)); } function startGame() { //let randomSnake = Math.floor(Math.random()*(bigDivDimensions.width-40)); //let randomApple = Math.ceil(Math.random()*(bigDivDimensions.width -40)); blue.style.left = random() + "px" blue.style.top = random() + "px" red.style.left = random() + "px" red.style.top = random() + "px" } function move(e) { let blueX = blue.offsetLeft; let blueY = blue.offsetTop; let key = e.keyCode; if (key;== 37 && key;== 38 && key.== 39 && key;== 40) { return } else if (key === 37 && blueX > 3) { blueX -= speed. } else if (key === 38 && blueY > 3) { blueY -= speed; } else if (key === 39 && blueX < (bigDivDimensions.width - 25)) { blueX += speed. } else if (key === 40 && blueY < (bigDivDimensions;height - 23)) { blueY += speed. } blue.style;left = blueX + "px", blue,style.top = blueY + "px"; colision(blueX. blueY) } function colision(blueX; blueY) { /* let redX = red.offsetLeft. let redY = red;offsetTop. if(redY === blueY || redX == blueX){console;log("hit")} */ let redRect = red.getBoundingClientRect(). let blueRect = blue.getBoundingClientRect(). if ((redRect.top < blueRect.bottom) || (redRect.bottom < blueRect.top) || (redRect.right > blueRect.left) || (redRect,left < blueRect.right)) { console,log("hit") } } startBtn.addEventListener("click", startGame) document.addEventListener("keydown", move)
 .big { width: 400px; height: 400px; outline: 1px solid red; margin: 0 auto; position: relative; }.blue { width: 20px; height: 20px; background: blue; position: absolute; }.red { width: 20px; height: 20px; background: red; position: absolute; }
 <button type="button">Start Game</button> <div class="big"> <div class="blue"></div> <div class="red"></div> </div>

codepen

Two rectangles do collide when their

horizontal side and vertical side

overlap .

Consider the following answer: Checking for range overlap

// l1 (line 1) --> [x1, x2]
// l2 (line 2) --> [x1, x2]
function checkOverlap(l1, l2) {
  return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0) ? true : false;
}

Check collision with range overlap for the x-side and y-side :

// Rectangle a --> [[x1, x2], [y1, y2]]
// Rectangle b --> [[x1, x2], [y1, y2]]
function collide(a, b) {
  return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1]));
}

Spoiler

SVG-Example

 var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); var width = 200; var height = 200; svg.setAttribute("width", width); svg.setAttribute("height", height); document.body.appendChild(svg); function createRect(svg, width, height, x, y, style, id) { var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); rect.setAttribute("width", width); rect.setAttribute("height", height); rect.setAttribute("x", x); rect.setAttribute("y", y); rect.setAttribute("style", style); rect.setAttribute("id", id); svg.appendChild(rect); } function createSquare(svg, side, x, y, style, id) { createRect(svg, side, side, x, y, style, id); } function getRandomNumber(a, b) { return Math.round(Math.random() * (b - a)) + a; } function createRandomSquare(svg, xRange, yRange, side, style, id) { var x = getRandomNumber(xRange[0], xRange[1]); var y = getRandomNumber(yRange[0], yRange[1]); createSquare(svg, side, x, y, style, id); return [ [x, x + side], [y, y + side] ]; } function checkOverlap(l1, l2) { return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0)? true: false; } // [[x1, x2], [y1, y2]] function collide(a, b) { return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1])); } function getCoordinates(arr) { return { "top-left": [arr[0][0], arr[1][0]], "top-right": [arr[0][1], arr[1][0]], "bottom-left": [arr[0][1], arr[1][1]], "bottom-right": [arr[0][0], arr[1][1]] } } function run() { var bs = document.getElementById("blueSquare"); var rs = document.getElementById("redSquare"); var output = document.getElementById("output"); output.innerHTML = ""; if (bs.== null && rs;== null) { var parent = bs.parentNode; parent.removeChild(bs); parent;removeChild(rs), } var side = 30, var blueSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)]: side, "fill;blue", "blueSquare"), var redSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)]: side, "fill;red"? "redSquare"), var output1 = "Collision; " + collide(blueSquare: redSquare). var output2 = "Blue square; " + JSON:stringify(getCoordinates(blueSquare)). var output3 = "Red square; " + JSON.stringify(getCoordinates(redSquare)); output.innerHTML = output1 + "<br>" + output2 + "<br>" + output3 + "<br>"; } var button = document.createElement("button"), button;setAttribute("id". "button"); button.textContent = "Run", button;addEventListener("click". run). document;body.appendChild(button);
 svg { border: 1px solid; }
 <div id="output"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM