2015-11-03 116 views
0

嗨我想獲得響應時2球對象碰撞在畫布上。球之間的碰撞檢測javascript

我有一個球對象ballm和一個叫ball的球對象。

這兩個球彈跳在畫布上。

如果球碰撞,畫布應該說遊戲結束。

下面是一個代碼我有碰撞到目前爲止

function collideWithBall() { 

       var dx = (ball.x + ball.radius) - (ballm.x + ballm.r); 
       var dy = (ball.y + ball.radius) - (ballm.y + ballm.r); 
       var distance = Math.sqrt((dx * dx) + (dy * dy)); 
       if (distance < ball.radius + ballm.r) {     

        ctx.clearRect(0, 0, canvas.width, canvas.height);  
        ctx.fillStyle = "black"; 
        ctx.font = "18px Arial"; 
        ctx.fillText("Game Over ", 300, 200); 
        shutdown(); 

       }   
      } 

我唯一的問題是,當2個球發生碰撞沒有任何反應。 任何想法都會非常有幫助。

完整代碼:

<!DOCTYPE html> 

<html> 

    <head> 
    <meta charset="UTF-8"> 
    <title>Canvas</title> 

    <style type="text/css"> 
     canvas { 
     border: 1px solid black; 
     } 
    </style> 

    </head> 

    <body> 

     <canvas id="tim's-game" width="800px" height="600px"></canvas> 

     <script type="text/javascript"> 
      // up top. creates the canvas with given dimensions 
      // declares script type 


      // Gets a handle to the element with id canvasOne.  
      var canvas = document.getElementById("tim's-game");  
      // Get a 2D context for the canvas.  
      var ctx = canvas.getContext("2d");  

      // Creates object for the balls 
      var ball = { 
       // determines the position where the ball will apear math.random gives a random position on the x ace 
       position: {x: Math.floor((Math.random() * 780) + 20), y: 10} 
       // Will determine the size of the ball 
       , radius: 6 
       // Will determine the speed of the ball 
       , velocity: {x: 3, y: 0} 
       // Will determine if the ball will get faster or slower 
       , acceleration: {x: 0, y: 0.1}   
       // Function that draws the ball 
       ,drawBall: function(){     
        // Collour of the object   
        ctx.fillStyle = "rgb(25, 100, 100)"; 
        // begins path 
        ctx.beginPath(); 
        // calls the object it will draw with positions and size 
        ctx.arc(ball.position.x, ball.position.y, ball.radius, 0, 2 * Math.PI); 
        // fills the colour 
        ctx.fill();  



        // Update the y location. 
        ball.velocity.y += ball.acceleration.y; 
        ball.position.x += ball.velocity.x; 
        ball.position.y += ball.velocity.y; 
        // Keep the animation going while the ball has not touched the canvas bottom. 
        // Note there's a bug here. 
        if ((ball.position.x >= canvas.width - ball.radius) || (ball.position.x <=     ball.radius)) 
         ball.velocity.x = -ball.velocity.x;  
        if ((ball.position.y >= canvas.height - ball.radius) || (ball.position.y <=    ball.radius)) 
         ball.velocity.y = -ball.velocity.y; 



       } 
       , 

      } 

      // Created a second ball object 
      var ball2 = { 
       // determines the position where the ball will apear math.random gives a random position on the x ace 
       position: {x: Math.floor((Math.random() * 780) + 20), y: 10} 
       // Will determine the size of the ball 
       , radius: 6 
       // Will determine the speed of the ball 
       , velocity: {x: 3, y: 0} 
       // Will determine if the ball will get faster or slower 
       , acceleration: {x: 0, y: 0.1}   
       // Function that draws the ball 
       ,drawBall2: function(){     
        // Collour of the object   
        ctx.fillStyle = "rgb(25, 100, 100)"; 
        // begins path 
        ctx.beginPath(); 
        // calls the object it will draw with positions and size 
        ctx.arc(ball2.position.x, ball2.position.y, ball2.radius, 0, 2 * Math.PI); 
        // fills the colour 
        ctx.fill();  


        // Update the y location. 
        ball2.velocity.y += ball2.acceleration.y; 
        ball2.position.x += ball2.velocity.x; 
        ball2.position.y += ball2.velocity.y; 
        // Keep the animation going while the ball has not touched the canvas bottom. 
        // Note there's a bug here. 
        if ((ball2.position.x >= canvas.width - ball2.radius) || (ball2.position.x <= ball2.radius)) 
         ball2.velocity.x = -ball2.velocity.x;  
        if ((ball2.position.y >= canvas.height - ball2.radius) || (ball2.position.y <= ball2.radius)) 
         ball2.velocity.y = -ball2.velocity.y; 
       } 
      } 


      // Creates a new ball object 
      // This ball will be used for moving around the canvas 
      var ballm = { 
       // spawns the ball in the middle of the canvas 
       position:{ x: canvas.width/2 
       , y: canvas.height/2 
       }, r: 50 

      }; 

      // Creates a draw circle function 
      function drawCircle() { 
       ctx.fillStyle = "rgb(255, 0, 0)"; 
       ctx.beginPath(); 
       ctx.arc(ballm.position.x, ballm.position.y, ballm.r, 0, 2 * Math.PI); 
       ctx.fill(); 

       collideWithBall(); 

      } 

      function collideWithBall() { 


       var dx = (ball.position.x + ball.radius) - (ballm.position.x + ballm.r); 
       var dy = (ball.position.y + ball.radius) - (ballm.position.y + ballm.r); 
       var distance = Math.sqrt((dx * dx) + (dy * dy)); 
       if (distance < ball.radius + ballm.r) {     

        ctx.clearRect(0, 0, canvas.width, canvas.height);  
        ctx.fillStyle = "black"; 
        ctx.font = "18px Arial"; 
        ctx.fillText("Game Over ", 300, 200); 
        shutdown(); 

       }   
      } 



      // A function to repeat every time the animation loops. 
      function repeatme() { 

       collideWithBall(); 
       // clears the screan/canvas i.e. where the ball was previously does not show up. 
       ctx.clearRect(0, 0, canvas.width, canvas.height); 
       // calls the function in the ball object 
       ball.drawBall(); 
       ball2.drawBall2(); 

       //calls the draw circle function 
       drawCircle(); 

       collideWithBall(); 
       // gets the animation going 
       window.requestAnimationFrame(repeatme); 
      } 

      // Add an event listener to the keypress event.   
      window.addEventListener("keydown", function(event) { 

       ctx.clearRect(0, 0, canvas.width, canvas.height); 

       // Right 
       if (event.keyCode == 39 && ballm.position.x < canvas.width - ballm.r) 
        ballm.position.x += Math.min(10, canvas.width - ballm.position.x - ballm.r); 

       // Left 
       else if (event.keyCode == 37 && ballm.position.x > ballm.r) 
        ballm.position.x -= 10; 

       // down 
       else if (event.keyCode == 40 && ballm.position.y < canvas.height - ballm.r) 
        ballm.position.y += 10; 

       // For up movement 
       else if (event.keyCode == 38 && ballm.position.y > ballm.r) 
        // updates location by int given 
        ballm.position.y -= 10; 

       drawCircle(); 
       collideWithBall(); 
      }); 


      // Get the animation going. 

      window.requestAnimationFrame(repeatme); 
    </script> 

    </body> 

</html> 

編輯:刪除了額外的collideWithBall功能。

也開始加入位置代碼

編輯2:添加修復了代碼工作現在

回答

2

你的數學錯在我看來。您的支票

if (distance < ball.radius + ballm.r) { 

是正確的,但表示距離是以球爲中心到中心測量的。因此,正確的距離公式是:

var dx = ball.position.x-ballm.x; 
var dy = ball.position.y-ballm.y; 
var distance = Math.sqrt((dx * dx) + (dy * dy)); 

球的半徑,如果你正在測量中心到中心的距離由if語句暗示不會進入計算。

的另一個問題,我可以在你的代碼中看到的是,

collideWithBall 

功能被定義了兩次!請嘗試刪除兩個看起來等效的實現之一。

編輯: 此外,您正在訪問錯誤的球位置。球的位置在位置屬性中。

因此你需要使用它!請參閱上面的編輯代碼。

作品則:http://jsfiddle.net/gQ3hD/2/

EDIT2:udpated小提琴也正確地遍歷在碰撞功能都巴力處理第二球。

+0

感謝您的信息,我嘗試了新的數學,但它仍然沒有采取碰撞。這個數學是從http://jsfiddle.net/gQ3hD/2/ –

+0

沒有更多的代碼這很難回答。 我的猜測是,雖然ctx對象在你的函數中不可用。 你能分享一個更完整的代碼片段嗎?或者爲了快速檢查,在所有函數之外聲明ctx並查看它是否工作正常? –

+0

據我所知,我已經添加了ctx對象在函數外部工作的孔代碼。 –