Skip to content

Flash向量-7-球和线

球和线

到现在你可能已经厌倦了总是只有一个移动的点。倒不是说点本身有什么不好,它们是好的,但是毕竟,点只是点。你能在你的周围能看到多少个点?我相信不会很多。最后,我们将向前迈进一大步,开始移动一些更加真实的东东西 – 球。

我相信你在生活中看到过很多的球,所以你知道他们和点有什么不同。球是有宽度的。在我们的2D例子中,球是用圆来表示的,它有圆心坐标并且有半径。

game.myOb={r:10};
game.myOb.p0={x:150, y:100};

已知一个运动的球的半径是10,另外我们知道球的中心坐标,它的移动向量和半径,我们要计算球撞上墙壁的会在哪儿。

图中,灰色的圈圈表示球的中心与墙壁的交点。事实上球在更早的时候就碰到墙壁了。球碰到墙壁的时候,球的位置应该这样的,将墙壁向量(green)向它的法线方向移动一个半径的距离,然后求出这个新的向量和球的运动向量(红色)的交点。所以,我们可以不使用墙壁向量,而是用一个方向相同,起点位置不同的向量。

Axes method

球和线的交点也可以用别的方法来计算。下面就来研究下如何通过一些简单的投影来确定球是否与墙壁碰撞。

图中,我们可以看到,球处于他的运动向量的终点p1处。我们绘制一个蓝色的向量,从墙壁向量的起点(v2.p0)出发,到达球的中心。现在我们将这个新的向量在墙壁的法线上进行投影,得到向量v3(红色)。为了将球紧贴墙壁放置,我需要将它向墙壁的法线方向移动:

ball.r-v3.len

在示例代码中,我们计算出墙壁法线的单位向量:

v.lx = v.dy;
v.ly = -v.dx;

在runme函数里,我们检查所有的墙壁:

for(var i=1; i<5; i++){
  var w=game["v"+i];
  //if we have hit the wall
  var pen=ob.r-findIntersection(ob, w);
  if(pen>=0){
    //move object away from the wall
    ob.p1.x+=w.lx*pen;
    ob.p1.y+=w.ly*pen;
    //change movement
    var vb=bounce(ob, w);
    ob.vx=vb.vx;
    ob.vy=vb.vy;
  }
}

对于每一个墙壁,如果球撞进去了,我们就计算出撞进去的距离,再将球拉回来,然后用之前同样的方法去计算反弹之后的向量。

计算撞进去的距离的函数:

function findIntersection(v1, v2){
  //vector between center of ball
  //and starting point of wall
  var v3={};
  v3.vx=v1.p1.x-v2.p0.x;
  v3.vy=v1.p1.y-v2.p0.y;
  //project this vector on the normal of the wall
  var v=projectVector(v3, v2.lx, v2.ly);
  //find length of projection
  v.len=Math.sqrt(v.vx*v.vx+v.vy*v.vy);
  return v.len;
}

在这个例子中,尝试拖动墙壁四个角的点:

注意,这个例子并没有考虑墙壁的长度,所有的墙壁都被认为是无限长的。这种方式可以用来保证球在盒子里面,而不会出去。在下一章节里面,我们会研究如何处理球和墙壁的角的碰撞。

你可以下载fla源文件

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*