点击浏览该文件这个函数就是碰撞检测的关键,我给它启名叫 "描边"
首先里面两个参数,第一个pmc就是要描边的mc,第二个num是要描的级数(等下会解释到),我们先可以先看下里面的逐句解释
function doFigure(pmc, num) { // 为pmc建立一个数组,数组的大小是num*2; pmc.point = new Array(num*2); // 从pmc的长和宽中取大的,然后除以2 var mx = Math.max(pmc._width, pmc._height)/2; // 把360℃num等分 var inc = 360/num; // 定义两个变量等下用 var n = 0; var i = 0; // while循环的次数为 i<num*2; while (i<(num*2)) { // 从下面n+=inc知道 xs和ys 就是每一个等分上x和y的所指的方向 var xs = Math.cos((n*Math.PI)/180); var ys = Math.sin((n*Math.PI)/180); // 以pmc的(x,y)点为定点,半径为mx的一个圆的轨迹 var x = pmc._x+(mx*xs); var y = pmc._y+(mx*ys); // 如果x,y没有接触到pmc上,不断循环 while (!pmc.hitTest(x, y, true)) { // x,y分别减 x -= xs; y -= ys; // 如果都小于0,就break跳出循环 if (x<0 && y<0) { break; } } // 把此时的x和y,分别计入point数组中 pmc.point[i] = x-pmc._x; pmc.point[i+1] = y-pmc._y; n += inc; i += 2; } } |
其实point里面就是记录了,一个图形的边缘的坐标.他是怎么做到的?
我们抛开所有从最里面的while循环讲起吧.
while的条件是,当(x,y)点没有接触到pmc的时候,就不断循环,循环的内容是 x-=xs,y-=ys;
如果我们前面什么也没看,应该可以想象,一开始(x,y)点一定在pmc的右边,然后不断的减一个数值xs,ys,直到减到x,y碰到pmc为止,这样,x,y就是pmc上的一点坐标了.
但是我们目前还不知道x和y是怎么定义的,还有就是xs和ys怎么来的
往上看
var xs = Math.cos((n*Math.PI)/180);
var ys = Math.sin((n*Math.PI)/180);
var x = pmc._x+(mx*xs);
var y = pmc._y+(mx*ys);
数学好的,一看就看出来了,这是圆的极坐标公式,就是以pmc的(x,y)为定点,mx为半径的圆的轨迹.var ys = Math.sin((n*Math.PI)/180);
var x = pmc._x+(mx*xs);
var y = pmc._y+(mx*ys);
看到这里,应该可以猜到,一定是让一些点以圆的方式出现在mc的周围,然后每个点往mc靠拢,知道每个点都靠到mc上面.
这样我们只要解决这个圆的大小问题了,也就是mx的大小,实际上,你把mx定义成一个很大的数也没问题,但是这样做,会浪费很多,对于写程序的来说,不必要的浪费是不行的^^
那么看上面的
var mx = Math.max(pmc._width, pmc._height)/2;
这里就定下了 mx的大小,也就是从mc的长和宽中找一个较大的出来,这样可以保证画出来的圆把整个mc都抱在了里面,大家看到除以2了吧,所以一定能想到 mc 的注册点一定是在中心哦(这也是关键之一^^)接着,和定义半径大小一样,我们做个360度每一度检测一下,也是可以的,但是这样做会很费资源,而且也没有必要那么精细.
所以才会有一个描边级数num,这个级数就是规定了,分num个等次来描,来记录num个点的坐标. 然后就是运用了
随便画个形状,在这个mc中写下面的代码,场景上再建立一个mc,命名为mc2
你可以看到,你的描边级数越高,每次检测的就越多,所以尽量减少就可以了,像我游戏里面只定义了10.
其实这只是一个大概的数据,并不是百分百的描边,不过这样已经够用了^^"
onClipEvent (load) { numb = 100; _root.doFigure(_name, numb); } onClipEvent (enterFrame) { _root.hit = false; i = 0; while (i < (numb * 2)) { x = points[i] + _x; y = points[i + 1] + _y; if (_root.mc2.hitTest(x, y, true)) { _root.hit = true; break; } i = i + 2; } } onClipEvent (mouseDown) { if (this.hitTest(_root._xmouse, _root._ymouse, true)) { this.startDrag(); } } onClipEvent (mouseUp) { this.stopDrag(); } |
