在不使用画布的情况下碰撞两个圆圈

时间:2018-10-26 14:59:18

标签: javascript javascript-objects

我创建了三个圆圈,并使其在不使用HTML画布的情况下从墙反弹。现在,我希望两个圆彼此碰撞并以相反的方向移动这些圆。我试图通过检查其位置来检测碰撞,但是它不起作用。我不知道哪里出了问题。 这是我的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Bounce Ball</title>
<meta name="viewport" content="width=device-width, initial-scale=1">  
<style>
    .circle{
        height: 50px;
        width: 50px;
        position: absolute; 
        border-radius: 50%;    
    }        
    .container {
        height: 300px;
        width: 300px;
        background-color: skyblue;
        position: relative;
    }
</style>
</head>
<body>
<div class ="container" id ="container">        
    <div class="circle" id = "circle1" style="background-color:black; 
    height: 50px; width: 50px;top:0; left:0"></div>  
    <div class="circle" id ="circle2" style="background-color:rgb(197, 100, 
    100);height: 50px; width: 50px;top:200px;left: 150px"></div>    
    <div class="circle" id ="circle3" style="background-color:brown;height: 
    50px;width: 50px;top:50px;left: 640px"></div>   
</div>
<script>
      var container = document.getElementById("container");
      container.style.width="700px";
      container.style.height = "300px";  
      var balls = document.getElementsByClassName("circle");   
      for(var i=0; i <balls.length; i++){
        var speed={x:3,y:-3}
        setInterval(draw, 50 , balls[i], speed);            
      }          
      function draw(ball, speed) { 
           if(parseInt(ball.style.left) > (parseInt(container.style.width)- 
      parseInt(ball.style.width)) || (parseInt(ball.style.left) <0) ){
                speed.x = -speed.x;                               
           } 
            ball.style.left = parseInt(ball.style.left) +  speed.x + 'px';                                       
           if(parseInt(ball.style.top) > (parseInt(container.style.height)- 
      parseInt(ball.style.height)) || (parseInt(ball.style.top) <0)){
               speed.y = -speed.y;
           }
             ball.style.top = parseInt(ball.style.top) + speed.y + 'px'; 
         //for colliding two circles
                    for(var i =0 ; i <= balls.length-1; i++){                  
                for(var j = i + 1; j < balls.length; j++){
                        if(parseInt(balls[i].style.left) + 
                 parseInt(balls[i].style.width) == 
                 parseInt(balls[j].style.left) || 
                 parseInt(balls[j].style.left) + 
                    parseInt(balls[j].style.width) == 
                   parseInt(balls[i].style.left) && 
                    parseInt(balls[i].style.top) + 
                    parseInt(balls[i].style.height) == 
               parseInt(balls[j].style.top) || parseInt(balls[j].style.top) 
               + parseInt(balls[j].style.height) == 
                  parseInt(balls[i].style.top)) {
                         speed.x = - speed.x; 
                         speed.y = -speed.y;                             
                    }
                    ball[i].style.left = parseInt(ball[i].style.left) + 
                         speed.x + 'px'; 
                    ball[j].style.left = parseInt(ball[j].style.left) + 
                         speed.x + 'px';                       
                    ball[i].style.top = parseInt(ball[i].style.top) + 
                    speed.y + 'px'; 
                    ball[j].style.top = parseInt(ball[j].style.top) + 
                        speed.y + 'px';                             
                }             

            }   

        }   

    </script>
    </body>
   </html>

1 个答案:

答案 0 :(得分:1)

我建议尽可能将其移入javascript变量,这样您就不必为每个参数都查阅HTML。

您有很多错别字,其中speed.x = - speed.x;就是您的意思speed.x = -speed.x;,而且如果没有任何注释或帮助函数来解释正在发生的情况,则很难阅读代码。

我已经修复了您的输入错误,并在下面的代码段中重组了代码。尝试检查开发者控制台typically by pressing F12,因为这将显示行号和严重性等级的代码错误。

在下面的代码段中,我尝试将参数移动到JavaScript中以显示其工作原理,同时仍将一些参数保留在HTML节点上:

//Basic properties
var width = 700;
var height = 300;
//Get container
var container = document.getElementById("container");
// Set dimensions
container.style.width = width + "px";
container.style.height = height + "px";
//Load balls
var balls = Array.prototype.slice.call(document.getElementsByClassName("circle"))
  .map(function(ball) {
    return {
      HTMLNode: ball,
      xPos: parseInt(ball.style.left),
      yPos: parseInt(ball.style.top),
      xAcc: 3,
      yAcc: -3,
      size: 50
    };
  });
//Utility functions
function angleBetween(x1, y1, x2, y2) {
  return Math.atan2(y2 - y1, x2 - x1);
}

function distanceBetween(x1, y1, x2, y2) {
  return Math.abs(y2 - y1) + Math.abs(x2 - x1);
}
//Draw function
function draw() {
  //Loop through balls
  for (var ballIndex1 = 0; ballIndex1 < balls.length; ballIndex1++) {
    var ball1 = balls[ballIndex1];
    //Collide with horisontal wall
    if (ball1.xPos > width - ball1.size || ball1.xPos < 0) {
      ball1.xAcc = -ball1.xAcc;
    }
    //Collide with vertical wall
    if (ball1.yPos > height - ball1.size || ball1.yPos < 0) {
      ball1.yAcc = -ball1.yAcc;
    }
    //Collide with other balls
    for (var ballIndex2 = ballIndex1 + 1; ballIndex2 < balls.length; ballIndex2++) {
      var ball2 = balls[ballIndex2];
      //Test within collision distance
      if (distanceBetween(ball1.xPos, ball1.yPos, ball2.xPos, ball2.yPos) > ball1.size) {
        continue;
      }
      //Get angle of collision
      var angle = angleBetween(ball1.xPos, ball1.yPos, ball2.xPos, ball2.yPos);
      //Apply force to acceleration
      ball1.xAcc = -Math.cos(angle) * 3;
      ball2.xAcc = -ball1.xAcc;
      ball1.yAcc = -Math.sin(angle) * 3;
      ball2.yAcc = -ball1.yAcc;
    }
    //Apply acceleration to position
    ball1.yPos += ball1.yAcc;
    ball1.xPos += ball1.xAcc;
    //Apply to node
    ball1.HTMLNode.style.left = ball1.xPos + "px";
    ball1.HTMLNode.style.top = ball1.yPos + "px";
  }
}
//Start simulation
setInterval(draw, 1000 / 60);
.circle {
  position: absolute;
  border-radius: 50%;
  height: 50px;
  width: 50px;
}

.container {
  height: 300px;
  width: 300px;
  background-color: skyblue;
  position: relative;
}
<div class="container" id="container">
  <div class="circle" id="circle1" style="background-color:black; 
    top:0; left:0"></div>
  <div class="circle" id="circle2" style="background-color:rgb(197, 100, 
    100);top:200px;left: 150px"></div>
  <div class="circle" id="circle3" style="background-color:brown;top:50px;left: 640px"></div>
</div>