碰撞可能检测 : 判断移动速率是否大于,球此时的位置到球碰撞位置的距离 这是最后一个判断,判断球A的速率是否小于判断是dis,如果是,说明下一帧时不会碰到,反之下一帧就要碰到了 OK,4个方法全部讲完,剩余的就是几何数学问题了^0^我们的detectCollision函数即如下 之前写的程序还是有错误和不妥之处 首先我一开始用的是方向和速率来控制移动,这样的话,在计算两球同时移动的时候,使用上面的碰撞检测就会出现很麻烦的事情--两球速度大小和方向--又要用到恐怖的数学三角函数~_~! 而如果只是用(vx,vy)来控制就方便的多,也就是说圆的x和y只要加上各自方向上的速度大小即可,如果要求角度的时候,再即时用Math.atan2来算就可以了,这样,速度的叠加就方便多了,比如
a_vx=1; a_vy=1; b_vx=-2; b_vy=-2; 那么速度叠加 大小
dvx=b_vx-a_vx; dvy=b_vy-a_vy; 方向
dir=Math.atan2(dvy,dvx); 这可比什么平行四边型法则容易太多了^^" ok,了解了以后,我把我的程序修改如下
///////////////////////////////////////////// /// **********08.14.2004 修改速度方向 /// 改去之前使用大小和方向的数学模式 /// 使用x,y方向的各自速度大小即时计算 /// **********08.15.2004 修改相对速度方向和球心之间的夹角 // 增加了求getTheta函数来求atan2时避免出现负角 ///////////////////////////////////////////// stop(); getRadii = function (mc) { return (Math.max(mc._width, mc._height)/2); }; getTheta = function (y, x) { var dir = Math.atan2(y, x); if (x>=0 && y>=0) { return dir; } else if (x>=0 && y<0) { return (dir+6.28); } else { return (dir+3.14); } }; function detectCollision(mc1, mc2) { // 第一种不碰撞可能检测 : 判断移动速率是否大于球表面距离 var sum_radii = mc1.radii+mc2.radii; var dx = mc2._x-mc1._x; var dy = mc2._y-mc1._y; var C = Math.sqrt(dx*dx+dy*dy); var dist = C-sum_radii; dxs = mc2.xsp-mc1.xsp; dys = mc2.ysp-mc1.ysp; var dsp = Math.sqrt(dxs*dxs+dys*dys); if (dsp return false; } // 第二种不碰撞可能检测 : 判断速度方向的夹角是否是钝角 var sdir = getTheta(dys, dxs); var cdir = getTheta(dy, dx); var theta = Math.abs(cdir-sdir); var D = C*Math.cos(theta); if (D<=0) { return false; } // 第三种不碰撞可能检测 : 判断被撞球圆心到撞球速度方向上垂直一点是否大于两球半径和 var F = Math.sqrt((C*C)-(D*D)); if (F>=sum_radii) { return false; } // 第四种不碰撞可能检测 : 判断移动速率是否大于,球此时的位置到球碰撞位置的距离 var T = Math.sqrt((sum_radii*sum_radii)-(F*F)); var disc = D-T; if (dsp return false; } return true; } function initialize() { toRadian = Math.PI/180; toAngle = 180/Math.PI; Math_rnd = Math.random; redBall.xsp = 10-Math_rnd()*20; redBall.ysp = 10-Math_rnd()*20; redBall.radii = getRadii(redBall); blueBall.xsp = 10-Math_rnd()*20; blueBall.ysp = 10-Math_rnd()*20; blueBall.radii = getRadii(blueBall); } initialize(); onEnterFrame = function () { redBall._x += redBall.xsp; redBall._y += redBall.ysp; blueBall._x += blueBall.xsp; blueBall._y += blueBall.ysp; if (detectCollision(redBall, blueBall)) { touch.text = "touch"; } else { touch.text = "no touch"; } };
| 源 |