安全删除Nape中的刚体
Nape中可以用space.bodies来获取所有刚体列表,我们可以用多种方法对其进项遍历,for,while,包括它自带的foreach()方法。
var i:int = 0; while (i < list.length) { var obj:Body = list.at(i); // obj操作 i++; } list.foreach(function (obj) { }); for (var i:int = 0; i < list.length; i++) { var obj:Body = list.at(i); }
有时候,我们需要批量性的删除某些特定刚体,这是可以在space.bodies中遍历中删除刚体,但是会影响游标的位置和列表的长度,有不可预知的风险,例如下面的示例中,我的初衷是按下空格键,删除物体上的所有圆形,并创建矩形刚体。再次按下空格键,删除所有矩形,创建圆形,以此类推。但是实际效果并不理想,每次的删除都不彻底,总有几个刚体混入到了另一个形状中去。点击图片查看Flash动态效果。
正确的做法时下面的BodyList的filter方法来删除。filter方法的结构如下:
list.filter(function (obj) { // operate on object. // ... return (false if you want object to be removed); });
其参数是一个回调函数,函数的参数是BodyList中的每个刚体,根据我们删除的条件对刚体进行判断,如果符合删除要求,则回调函数返回false,否则返回true,例如下面的代码,可以讲space中的所有动态刚体都删除。
list.filter(function(b:Body):Boolean{ return b.type!=BodyType.DYNAMIC; });
完整代码如下:
package { import flash.events.KeyboardEvent; import flash.ui.Keyboard; import ldEasyNape.LDEasyBody; import nape.phys.Body; import nape.phys.BodyList; import nape.phys.BodyType; public class RemoveBodySafely extends AbstractNapeTest { public function RemoveBodySafely(gravity:Number=600) { super(gravity); } private var typeIndex:int=0; override protected function onNapeAppReady():void { LDEasyBody.createRectangle(0,0,stage.stageWidth,stage.stageHeight); createBodies(); } private function createBodies():void { if(++typeIndex>1) typeIndex =0; for (var i:int = 0; i < 10; i++) { var px:Number = Math.random()*400+50; var py:Number = Math.random()*300+50; var size:Number = Math.random()*40+20; if(typeIndex==0){ LDEasyBody.createCircle(px+size,py,size/2); }else{ LDEasyBody.createBox(px,py,size,size); } } } override protected function keyBoardEventHanlder(event:KeyboardEvent):void { if(event.type == KeyboardEvent.KEY_DOWN && event.keyCode == Keyboard.SPACE){ clearBodies(); createBodies(); } } private function clearBodies():void { var list:BodyList = space.bodies; var tempBody:Body; // 错误的写法 // for (var i:int = 0; i < list.length; i++) // { // tempBody = list.at(i); // if(tempBody.type== BodyType.DYNAMIC){ // list.remove(tempBody); // } // } //正确的写法 list.filter(function(b:Body):Boolean{ return b.type!=BodyType.DYNAMIC; }); } } }
重点在49~65行的clearBodies()函数中,包括了真确和错误的方法,你可以试着把错误方法的注释去掉,查看不同的效果。点击下载源文件
联系作者
支持下
谢谢支持!欢迎继续关注我的物理教程!
其实把遍历的顺序倒过来就可以了,如:
var i:int = bodies.length;
while(–i>=0){
if(bodies.at(i).type==BodyType.DYNAMIC)
bodies.remove(bodies.at(i));
}
恩,这也是个方法,领教啦!