安全删除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动态效果。

wrongRemove
正确的做法时下面的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;
});

rightRemove

完整代码如下:

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()函数中,包括了真确和错误的方法,你可以试着把错误方法的注释去掉,查看不同的效果。点击下载源文件

联系作者

公众号:拉小登 | 微博:拉登Dony | B站:拉小登Excel

4 Replies to “安全删除Nape中的刚体”

  1. 其实把遍历的顺序倒过来就可以了,如:
    var i:int = bodies.length;
    while(–i>=0){
    if(bodies.at(i).type==BodyType.DYNAMIC)
    bodies.remove(bodies.at(i));
    }

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注