LDEasyNape vs LDEasyBox2D

大家都知道LDEasyBox2D可以帮我们简化Box2D应用的创建过程。近期拉登大叔也在研究Nape,虽说Nape的用法比Box2D要简单不少,但是用惯了LDEasyBox2D,还是觉得有点繁杂,所以拉登大叔也写了一个LDEasyNape。

与此同时也对LDEasyBox2D做了一些修改,统一了LDEasyNape和LDEasyBox2D的函数,可以用相同的方法创建Nape或Box2D方法。闲话少说,我们来看看具体的用法。

大体的步骤如下:

  1. 用initialize(stage:Stage,napeFps:uint=60)方法设置LDEasyNape引用的Flash舞台对象,以及模拟帧频(默认为60)。
  2. 用createDebug()方法创建模拟视图,同时将返回的BitmapDebug对象的display属性添加到舞台上。
  3. 利用createCircle、createBox、createRegular等等方法快速创建刚体
  4. 在EnterFrame事件处理函数中调用updateWorld()更新Nape空间模拟。

另外和以前的LDEasyBox2D一样,我们还可以用getBodyAtMouse()方法获取鼠标位置处的刚体,用startDragBody和stopDragBody方法开始或停止拖动刚体。

依然很简单,不过在使用时不用再设置stage等其他属性了,接口更加简化了,相同的方法可以用在LDEasyBox2D和LDEasyNape上,同一了两个物理引擎的用法。下面是LDEasyBox2D和LDEasyNape在Google Code上是地址,你可以在这里获得的最新的LDEasy类。

LDEasyBox2D:http://code.google.com/p/ldeasybox2d/

LDEasyNape:http://code.google.com/p/ldeasynape/

除了统一了这两个类之外,我还自定义了一个LDEasyUserData类,同样都适用于LDEasyBox2D和LDEasyNape。LDEasyUserData中有两个公共方法setGraphicAuotmatically和setGraphic,它们的用法如下:

  • setGraphicAuotmatically:通过这个方法的参数可以快速设置由单色填充的自定义刚体视图
  • setGraphic:设置开发者自定义的刚体视图

然后在创建刚体的createCircle、createBox、createRegular等方法的最后一个参数中设置LDEasyUserData对象,快速创建自定义视图。

同时LDEasyUserData也是一个动态类,使用时你可以随意添加新的属性。下面是Nape贴图里的示例用LDEasyNape和LDEasyUserData实现的代码,看,是不是简单了许多?

下面的示例中,同时Box2D和Nape创建了刚体,红色刚体是Box2D的,蓝色是Nape的,鼠标点击可以拖动刚体。

[swfobject]796[/swfobject]

代码中,我定了createNapeWorld()和createBox2DWorld()两个方法,分别创建Nape和Box2D的应用,对比一样,基本都是一样的,代码很简单,我就不逐一解释了,大家直接看代码吧!

package  
{
	import flash.display.Sprite;
	import Box2D.Dynamics.b2World;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import nape.space.Space;

	import ldEasyBox2D.LDEasyBox2D;
	import ldEasyBox2D.LDEasyUserData;
	import ldEasyNape.LDEasyNape;
	import ldEasyNape.LDEasyUserData;

	/**
	 * ...
	 * @author ...
	 */
	public class LDEasyPhysicEngine extends Sprite 
	{
		private var napeWorld:Space;
		private var box2DWorld:b2World;

		public function LDEasyPhysicEngine() 
		{
			createNapeWorld();
			createBox2DWorld();

			stage.addEventListener(Event.ENTER_FRAME, loop);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseEventHandler);
		}

		private function createBox2DWorld():void 
		{
			LDEasyBox2D.initialize(stage, 60);
			LDEasyBox2D.createWorld(0,0);
			addChild(LDEasyBox2D.createDebug().GetSprite());
			LDEasyBox2D.createWrapWall();

			var ud:ldEasyBox2D.LDEasyUserData = new ldEasyBox2D.LDEasyUserData();
			ud.setGraphicAuotmatically(0xff0000);

			for(var i:int=0; i<10; i++){
				var randomseed:Number=Math.random();
				var posX:Number = Math.random()*500 + 25;
				var posY:Number = Math.random()*300 + 50;

				if(randomseed<0.25){
					LDEasyBox2D.createBox(posX, posY, 30, 30,false,false,ud.clone());
				}else if(randomseed<0.5){
					LDEasyBox2D.createRegular(posX, posY, 30,5, 0,false, false, ud.clone());
				}else if(randomseed<0.75){
					LDEasyBox2D.createRegular(posX, posY, 30,3, 0,false, false, ud.clone());
				}else{
					LDEasyBox2D.createCircle(posX, posY, 30,false,false,ud.clone());
				}

			}
		}

		private function createNapeWorld():void 
		{
			LDEasyNape.initialize(stage, 60);
			LDEasyNape.createWorld(0,0);
			addChild(LDEasyNape.createDebug().display);
			LDEasyNape.createWrapWall();

			var ud:ldEasyNape.LDEasyUserData = new ldEasyNape.LDEasyUserData;
			ud.setGraphicAuotmatically(0x0000ff);
			for(var i:int=0; i<10; i++){
				var randomseed:Number=Math.random();
				var posX:Number = Math.random()*500 + 25;
				var posY:Number = Math.random()*300 + 50;

				if(randomseed<0.25){
					LDEasyNape.createBox(posX, posY, 30, 30,false,false,ud.clone());
				}else if(randomseed<0.5){
					LDEasyNape.createRegular(posX, posY, 30,5, 0,false, false, ud.clone());
				}else if(randomseed<0.75){
					LDEasyNape.createRegular(posX, posY, 30,3, 0,false, false, ud.clone());
				}else{
					LDEasyNape.createCircle(posX, posY, 30,false,false,ud.clone());
				}

			}
		}
		private function mouseEventHandler(event : MouseEvent) : void {
			switch(event.type){
				case MouseEvent.MOUSE_DOWN:
					LDEasyNape.startDragBody(LDEasyNape.getBodyAtMouse());
					LDEasyBox2D.startDragBody(LDEasyBox2D.getBodyAtMouse());
					break;
				case MouseEvent.MOUSE_UP:
					LDEasyNape.stopDragBody();
					LDEasyBox2D.stopDragBody();
					break;
				default:
			}
		}
		private function loop(event : Event) : void {
			LDEasyNape.updateWorld();
			LDEasyBox2D.updateWorld();
		}

	}

}

点击这里下载完整的源文件

 

联系作者

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

3 Replies to “LDEasyNape vs LDEasyBox2D”

  1. 拉登叔,在您的这个DEMO中,拖动NAPE物体时,debugdraw的边框与贴图会出现不同步的情况。

    在LDEASYNAPE.AS 中154行

    public static function updateWorld():void{
    for(var i:int=0; i<world.liveBodies.length;i++){
    var body:Body=world.liveBodies.at(i);
    var graphic:DisplayObject=body.userData.graphic;
    var position:Vec2=body.position;
    if(graphic!=null){
    graphic.x=position.x;
    graphic.y=position.y;
    graphic.rotation=(body.rotation*180/Math.PI)%360;
    }
    }

    world.step(1/LDEasyNape.napeFps);
    if(napeDebug!=null){
    napeDebug.clear();
    napeDebug.draw(world);
    napeDebug.flush();
    }
    if(hand!=null){
    if(hand.active) hand.anchor1.setxy(stage.mouseX,stage.mouseY);
    }
    }

    nape的贴图部分与debug部分被 world.step(1/LDEasyNape.napeFps); 隔开了,导致贴图总比debug慢一帧。

回复 zhangandi

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