Canvas物體碰撞

Canvas標籤可以很方便的畫出圖形,再加上物理公式可以很簡單的模擬出物體跑碰撞效果:

 

<!DOCTYPE HTML>

<html>

 

<head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <title>game</title>

  <meta name="Author" content="">

  <meta name="Keywords" content="">

 

  <script language="javascript" type="text/javascript" src="jquery.js"></script>

  <script language="javascript" type="text/javascript" src="game.js"></script>

</head>

<body>

 

 

<div id="box" style="width:800px;height:600px;border:1px solid #000;margin:10px auto;"></div>

 

 

 

<script>

 

 

var CANVAS_WIDTH = 800;

var CANVAS_HEIGHT = 600;

 

var canvasElement = $("<canvas width='" + CANVAS_WIDTH +

                      "' height='" + CANVAS_HEIGHT + "'></canvas>");

var canvas = canvasElement.get(0).getContext("2d");

canvasElement.appendTo('#box');

 

var FPS = 40; //動畫的每秒幀

var balls=[]; //運動的球集合

var player = {

  color: "#00A",  //球體顏色

  x: 400,

  y: 300,  //球體座標

  r:32,    //半徑

  vx:0,// x軸速度

  vy:0,// y軸速度

  draw: function() { //畫圖方法

    canvas.fillStyle = this.color;

  

       canvas.beginPath();

       canvas.arc(this.x, this.y,this.r,0,Math.PI * 2,true);

       canvas.fill();

  }

};

 

balls.push(player);

var ball = {

  color: "#ff0",

  x: 700,

  y: 200,

  r:20,

  vx:-5,

  vy:2,

  draw: function() {

    canvas.fillStyle = this.color;

      canvas.beginPath();

       canvas.arc(this.x, this.y,this.r,0,Math.PI * 2,true);

       canvas.fill();

  }

};

balls.push(ball);

 

var b1 = {

  color: "#f00",

  x: 100,

  y: 300,

  r:20,

  vx:3,

  vy:-4,

  draw: function() {

    canvas.fillStyle = this.color;

      canvas.beginPath();

       canvas.arc(this.x, this.y,this.r,0,Math.PI * 2,true);

       canvas.fill();

  }

};

balls.push(b1);

 

function distanceTo(b1,b2){ //計算2點距離

      

       var dx = b1.x - b2.x,

              dy = b1.y - b2.y;

      

       return Math.sqrt(dx * dx + dy * dy);

}

 

 

function update(){ //每幀動畫實現

 

  for (var i=0,l=balls.length;i<l;i++){

 

  balls[i].x += balls[i].vx;

  balls[i].y += balls[i].vy;

 

  if (balls[i].r + balls[i].x > CANVAS_WIDTH || balls[i].x<balls[i].r){ balls[i].vx *= -1;}  //到邊界則速度方向相反

  if (balls[i].r + balls[i].y > CANVAS_HEIGHT || balls[i].y < balls[i].r){ balls[i].vy *= -1;}

   };

 

  for (var i=0,l=balls.length;i<l-1;i++)

  {

       for(var j=i+1;j<l;j++)

       {

       var ball1 = balls[i],

              ball2 = balls[j],

              distance = distanceTo(ball1,ball2);  //計算2球中心距離

       if(distance <= ball1.r + ball2.r){ //如果2球心距離小於 2球的半徑之和則會發生碰撞

              //碰撞後速度計算方法

              var cosAngle = (ball1.x - ball2.x) / distance;

              var sinAngle = (ball1.y - ball2.y) / distance;

              var b1vx = ball1.vx;

              var b1vy = ball1.vy;

              var b2vx = ball2.vx;

              var b2vy = ball2.vy;

              ball2.vx += (b1vx * cosAngle * cosAngle + b1vy * sinAngle * cosAngle - b2vx * cosAngle * cosAngle - b2vy * sinAngle * cosAngle);

              ball2.vy += (b1vx * cosAngle * sinAngle + b1vy * sinAngle * sinAngle - b2vx * cosAngle * sinAngle - b2vy * sinAngle * sinAngle);

              ball1.vx += (-b1vx * cosAngle * cosAngle - b1vy * sinAngle * cosAngle + b2vx * cosAngle * cosAngle + b2vy * sinAngle * cosAngle);

              ball1.vy += (-b1vx * cosAngle * sinAngle - b1vy * sinAngle * sinAngle + b2vx * cosAngle * sinAngle + b2vy * sinAngle * sinAngle);

              balls[i] = ball1;

              balls[j] = ball2;

        }

       }

  }

 

}

 

 

 

function draw(){

  canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

 

  $(balls).each(function(i){

  balls[i].draw();

  });

 

}

 

$(function(){

var timer =     setInterval(function() {

         update();

         draw();

       }, 1000/FPS);

 

});

 

</script>

 

</body>

</html>

發佈了54 篇原創文章 · 獲贊 42 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章