如何使用javascript和canvas标签使属于同一个数组的两个对象彼此独立移动?

时间:2016-02-02 18:40:08

标签: javascript html5 canvas

我正在尝试创建一个黑洞模拟,其中所有的球都以给定的速度离开它,落在它上面的球被拖向圆圈直到它们到达它的中心,在那里它们会停下来消失,这是我的代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>blackhole simulation escape velocity</title>
        <script>
            var canvas, ctx;
            var blackhole;
            var circle;
            var circles = new Array();
            var G = 6.67e-11, //gravitational constant
            pixel_G = G / 1e-11,
            c = 3e8, //speed of light (m/s)
            M = 12e31, // masseof the blackhole in kg (60 solar masses)
            pixel_M = M / 1e32
            Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
            pixel_Rs = Rs / 1e3, // scaled radius 
            ccolor = 128;

            function update() {
                var pos, i, distance, somethingMoved = false;
                for (i = 0; i < circles.length; i++) {
                    pos = circles[i].position;
                    distance = Math.sqrt(((pos.x - 700) * (pos.x - 700)) + ((pos.y - 400) *   (pos.y - 400)));
                   if (distance > pixel_Rs-5 ) {
                       var delta = new Vector2D(0, 0);
                       var forceDirection = Math.atan2(pos.y - 400, pos.x - 700);
                       var evelocity = Math.sqrt((2 * pixel_G * pixel_M) / (distance * 1e-2));
                       delta.x += Math.cos(forceDirection) * evelocity;
                       delta.y += Math.sin(forceDirection) * evelocity;
                       pos.x += delta.x;
                       pos.y += delta.y;
                       somethingMoved = true;
                   } else {
                       var delta2 = new Vector2D (0,0);
                       var forceDirection2 = Math.atan2(pos.y - 400, pos.x - 700);
                       var g = (pixel_G*pixel_M)/(distance*distance*1e2);
                       delta2.x += Math.cos(forceDirection2)*g;
                       delta2.y += Math.sin(forceDirection2)*g;
                       pos.x -= delta2.x;
                       pos.y -= delta2.y;
                       somethingMoved = true;
                       circles[i].color -= 1;

                       if (pos.x == 700 && pos.y == 400){
                           somethingMoved = false;
                       };

                   }
               }
               if (somethingMoved) {
                   drawEverything();
                   requestAnimationFrame(update);
               };
           }

           function drawEverything() {
               ctx.clearRect(0, 0, canvas.width, canvas.height);
               blackhole.draw(ctx);
               for (var i = 0; i < circles.length; i++) {
                   circles[i].draw(ctx);
               }
           }

           function init(event) {
               canvas = document.getElementById("space");
               ctx = canvas.getContext('2d');
               blackhole = new Ball(pixel_Rs, { x: 700,
                                                y: 400 }, 0);

               for (var i = 0; i < 200; i++) {
                   var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
                   circle = new Ball(5, vec2D, ccolor);
                   circles.push(circle);
               }
               drawEverything();
               requestAnimationFrame(update);
           }

           function Ball(radius, position, color) {
               this.radius = radius;
               this.position = position;
               this.color = color;
           }

           Ball.prototype.draw = function(ctx) {
               var c=parseInt(this.color);
               ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',1)';
               ctx.beginPath();
               ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
               ctx.closePath();
               ctx.fill();
           };

           function Vector2D(x, y) {
               this.x = x;
               this.y = y;
           }


           function onClick (){
               canvas = document.getElementById ('space');
               ctx = canvas.getContext ('2d') 
               canvas.addEventListener ("mousedown", init, false)
               blackhole = new Ball (5, {x: 700,
                                         y: 400 }, 0);
               blackhole.draw (ctx) ;                   

           }  
           window.onload = onClick;

        </script>
        <style>
            body {
                background-color:#021c36 ;
                margin: 0px;
            }
        </style>
    </head>
    <body>
        <canvas id = "space", width = "1400", height = "800">
        </canvas>
    </body>
</html>

现在你可以看到,我创建了一个名为delta2的第二个变量,但问题是它无法更新圆圈的位置,这在一定程度上无法移动圆圈,有人能告诉我怎么了。另外,如何在一定时间后制作大黑圈,我知道我应该创建一个计时器,但我不知道它们是如何工作的

1 个答案:

答案 0 :(得分:0)

引力太弱了。我用伪引力来演示。

var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();

var bh = {
  w:500,
  h:300
};

bh.cx = Math.floor(bh.w/2);
bh.cy = Math.floor(bh.h/2)


var G = 6.67e-11, //gravitational constant
  pixel_G = G / 1e-11,
  c = 3e8, //speed of light (m/s)
  M = 12e31, // masseof the blackhole in kg (60 solar masses)
  pixel_M = M / 1e32
Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
  pixel_Rs = Rs / 1e3, // scaled radius 
  ccolor = 128;

function update() {
  var pos, i, distance, somethingMoved = false;
  for (i = 0; i < circles.length; i++) {
    pos = circles[i].position;
    distance = Math.sqrt(((pos.x - bh.cx) * (pos.x - bh.cx)) + ((pos.y - bh.cy) * (pos.y - bh.cy)));
    if (distance > pixel_Rs - 5) {
      var delta = new Vector2D(0, 0);
      var forceDirection = Math.atan2(pos.y - bh.cy, pos.x - bh.cx);
      var evelocity = Math.sqrt((2 * pixel_G * pixel_M) / (distance * 1e-2));
      delta.x += Math.cos(forceDirection) * evelocity;
      delta.y += Math.sin(forceDirection) * evelocity;
      pos.x += delta.x;
      pos.y += delta.y;
      somethingMoved = true;
    } else {
      var delta2 = new Vector2D(0, 0);
      var forceDirection2 = Math.atan2(pos.y - bh.cy, pos.x - bh.cx);
      // FIX THIS!!!
      var g = 1;//(pixel_G * pixel_M) / (distance * distance * 1e2);
      delta2.x += Math.cos(forceDirection2) * g;
      delta2.y += Math.sin(forceDirection2) * g;
      pos.x -= delta2.x;
      pos.y -= delta2.y;
      somethingMoved = true;
      circles[i].color -= 1;

      if (pos.x == bh.cx && pos.y == bh.cy) {
        somethingMoved = false;

      };

    }
  }
  if (somethingMoved) {
    drawEverything();
    requestAnimationFrame(update);
  };
}



function drawEverything() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  blackhole.draw(ctx);
  for (var i = 0; i < circles.length; i++) {
    circles[i].draw(ctx);
  }
}

function init(event) {
  canvas = document.getElementById("space");
  canvas.width = bh.w;
  canvas.height = bh.h;
  ctx = canvas.getContext('2d');
  blackhole = new Ball(5, { //pixel_Rs, {
    x: bh.cx,
    y: bh.cy
  }, 0);

  for (var i = 0; i < 200; i++) {
    var vec2D = new Vector2D(Math.floor(Math.random() * bh.w), Math.floor(Math.random() * bh.h));
    circle = new Ball(5, vec2D, ccolor);
    circles.push(circle);
  }
  drawEverything();
  requestAnimationFrame(update);
}

function Ball(radius, position, color) {
  this.radius = radius;
  this.position = position;
  this.color = color;
}

Ball.prototype.draw = function(ctx) {
  var c = parseInt(this.color);
  ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',1)';
  ctx.beginPath();
  ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
  ctx.closePath();
  ctx.fill();
};

function Vector2D(x, y) {
  this.x = x;
  this.y = y;
}


function onClick() {
  canvas = document.getElementById('space');
  ctx = canvas.getContext('2d')
  canvas.addEventListener("mousedown", init, false)
  blackhole = new Ball(5, {
    x: bh.cx,
    y: bh.cy
  }, 0);
  blackhole.draw(ctx);

}
window.onload = onClick;
body {
  background-color: #021c36;
  margin: 0px;
}
<canvas id="space" , width="700" , height="400"></canvas>