检测2个divs javascript之间的“碰撞”

问题描述 投票:1回答:1

我想检测两个div之间的冲突,并且我尝试使用每个div的offsetLeft和offsetTop并使用getBoundingClientRect()来做到这一点。但这些都不起作用

有没有一种方法可以获取这两个元素接触的确切坐标?

我该怎么做?

codepen-> https://codepen.io/mullerz/pen/vYNjXWQ

<button type="button">Start Game</button>
    <div class="big">
        <div class="blue"></div>
        <div class="red"></div>
    </div>
.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;
    }
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)
javascript
1个回答
0
投票

[两个矩形在发生碰撞时发生碰撞

水平侧和垂直侧

重叠。

请考虑以下答案: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;
}

检查x侧y侧的范围重叠的碰撞:

// 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]));
}

扰流板

SVG示例

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, bg, 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", `fill:${bg}`);
  rect.setAttribute("id", id);
  svg.appendChild(rect);
}

function createSquare(svg, side, x, y, bg, id) {
  createRect(svg, side, side, x, y, bg, id);
}

function getRandomNumber(a, b) {
  return Math.round(Math.random() * (b - a)) + a;
}

function createRandomSquare(svg, xRange, yRange, side, bg, id) {
  var x = getRandomNumber(xRange[0], xRange[1]);
  var y = getRandomNumber(yRange[0], yRange[1]);
  createSquare(svg, side, x, y, bg, 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 run() {
  var bs = document.getElementById("blueSquare");
  var rs = document.getElementById("redSquare");
  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, "blue", "blueSquare");
  var redSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)], side, "red", "redSquare");
  console.log(collide(blueSquare, redSquare));
}

var button = document.createElement("button");
button.setAttribute("id", "button");
button.textContent = "Run";
button.addEventListener("click", run);
document.body.appendChild(button);
svg {
  border: 1px solid;
}
© www.soinside.com 2019 - 2024. All rights reserved.