创建简单的Nape刚体

认识Nape空间里,看我们了解了这个2D物理引擎,并学习了如何创建一个基本的Nape应用,今天我们来学习一下如何创建一些简单的Nape刚体。

运动与静止的刚体

和Box2D一样,Nape中的也分为静止和运动刚体,对应静止的刚体将不进行物理运动模拟,这样可以节省CPU的开支。我们可以通过刚体的type属性设置刚体的类型,这个属性值可以是DYNAMIC、STATIC或KINEMATIC,分别表示运动的、静止的和不受力作用但可以运动的静态刚体。

	var body:Body = new Body(BodyType.DYNAMIC,new Vec2(bx,by));

设置刚体的形状

Nape刚体的形状是通过body.shape属性来设置的,和Box2D不一样,这个shape属性是一个shapeList类对象,也就是说,我们无法直接给shape属性赋值,而是要通过body.shape.addShape()方法来添加刚体形状。

addShape()方法有一个Shape类型的参数,实际上我们通常都是使用Shape类的子类Circle和Polygon来设置刚体的形状,Shape类只有两个子类,但不代码刚体就只有两个形状。具体说明如下:

Circle类

Circle用来创建一个圆形对象。构造函数和相应的参数说明如下:

function Circle(
			radius:Float, 
			localCOM:Vec2, 
			material:Material, 
			filter:InteractionFilter
		)
  • radius:圆形的半径,以像素为单位
  • localCOM:圆形的重心,即质量的中心,默认为(0,0)
  • material:圆形的材质,比如弹性、摩擦系数等,都通过material属性设置,相当于Box2D里的b2FixtureDef,默认为null。以后我会再详细介绍material的用方法
  • filter:设置刚体的碰撞分组,相当于Box2D中的FilterData

Polygon类

Polygon类会根据制定的一组顶点,来创建一个多边形对象。顶点的个数和坐标不同,就可以创建多各种各样的形状。它的构造函数和参数说明如下:

		public function Polygon (
			localVerts:*, 
			material:Material = null, 
			filter:InteractionFilter = null
			);
  • localVerts:表示一个保存了多边形顶点的数组。Polygon中有一些静态方法,如box(),可以帮我们返回一些简单的顶点数组,Polygon.box()也是我们创建矩形刚体常用的方法。
  • material:多边形的材质,比如弹性、摩擦系数等,都通过material属性设置,相当于Box2D里的b2FixtureDef,默认为null
  • filter:设置刚体的碰撞分组,相当于Box2D中的FilterData

总的来看,Nape刚体的创建过程要比Box2D简单一些,至少不用创建一大堆的b2Shape,b2FixtureDef,b2Fixture,b2BodyDef和b2Body对象,这么多对象,看着都头疼。所以Nape还是很值得学习的哦!

言归正传,认识了Circle和Polygon类之后,我们就可以创建简单的圆形和矩形刚体了(复杂的多边形Nape刚体,稍候我会陆续讲解)。

		//创建圆形的Nape刚体
		private function createCircle(posX:Number, posY:Number, radius:int, type:BodyType):void
		{
			//创建刚体,Body有两个参数,一个是指刚体的类型,一个是指刚体的坐标
			var circle:Body = new Body(type, new Vec2(posX, posY));
			//创建刚体形状,刚体形状类型有两种:Circle或Polygon,但不代表刚体形状只有两种,Polygon类可以创建出各种形状的多边形刚体形状
			//第二个参数的Material对象,我只传入了一个参数,表示刚体的弹性系数,后续我会专门介绍material类。
			var shape:Circle = new Circle(radius, null, new Material(1));
			//刚体的shapes是一个ShapeList类型的对象,不能直接将Shape对象复制给它,要通过push,将形状添加到ShapeList中去
			circle.shapes.push(shape);
			//设置刚体的空间
			circle.space=space;
		}
		//创建矩形的Nape刚体
		private function createBox(posX:Number,posY:Number,width:Number,height:Number,type:BodyType, angle:Number=0):Body{
			//创建刚体,Body有两个参数,一个是指刚体的类型,一个是指刚体的坐标
			var box:Body = new Body(type, new Vec2(posX, posY));
			//创建刚体形状,刚体形状类型有两种:Circle或Polygon,但不代表刚体形状只有两种,Polygon类可以创建出各种形状的多边形刚体形状
			//Polygon.box()方法会返回一个保存了指定宽高的矩形4个顶点的数组,然后将这个数组传入到Polygon的第一个参数中,矩形就创建好了
			var shape:Polygon = new Polygon(Polygon.box(width, height));
			//创建一定的角度,单位是弧度
			shape.rotate(angle);
			//刚体的shapes是一个ShapeList类型的对象,不能直接将Shape对象复制给它,要通过push,将形状添加到ShapeList中去
			box.shapes.push(shape);
			//设置刚体的空间
			box.space=space;

			return box;
		}

虽然今天只是学习了运动和静止的刚体,以及创建简单的形状,不过只要发挥想象力,我们一样可以作出很有趣的效果。像下面的示例,就是利用今天的知识,仿真出的<神奇的阿力>第一关的效果。

[swfobject]642[/swfobject]

完整的代码和注释如下:

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import nape.phys.Material;

	import nape.geom.Vec2;
	import nape.phys.Body;
	import nape.phys.BodyType;
	import nape.shape.Circle;
	import nape.shape.Polygon;
	import nape.space.Space;
	import nape.util.Debug;
	import nape.util.ShapeDebug;

	//[SWF(frameRate="60", width=550, height=400, backgroundColor="0xCCCCCC")]
	public class Main extends Sprite
	{
		//声明一个Nape空间
		private var space:Space;
		//声明一个调试视图
		private var debug:ShapeDebug;

		public function Main()
		{
			//1.创建Nape空间
			//设置空间的重力,和Box2D的单位不一样
			var gravity:Vec2=new Vec2(0,500);
			space=new Space(gravity);

			//2.创建调试视图
			debug = new ShapeDebug(550, 400, 0x0000ff);
			//我们不用像Box2D专门创建一个Sprite对象,ShapeDebug就已经包含了一个显示对象属性display
			//直接添加到舞台上就可以了。
			addChild(debug.display);

			//3.创建刚体
			createBodies();

			//添加左上角的FPS监视器
			addChild(new Stats());
			//4.添加事件侦听器
			addEventListener(Event.ENTER_FRAME,loop);
		}

		private function createBodies():void
		{
			//上面的三个板板
			createBox(92, 130, 120, 15, BodyType.STATIC,Math.PI/6);
			createBox(208, 163, 120, 15, BodyType.STATIC);
			createBox(350, 163, 144, 15, BodyType.STATIC);

			//下面的三个板板
			createBox(483, 223, 120, 15, BodyType.STATIC,-Math.PI/6);
			createBox(360, 255, 120, 15, BodyType.STATIC);
			createBox(232, 255, 120, 15, BodyType.STATIC);

			//下面的槽
			createBox(49, 297, 15, 70, BodyType.STATIC);
			createBox(157, 297, 15, 70, BodyType.STATIC);
			createBox(100, 325, 120, 15, BodyType.STATIC);

			//活动的两个挡板
			createBox(200, 120, 15, 100, BodyType.DYNAMIC);
			createBox(300, 120, 15, 100, BodyType.DYNAMIC);

			//创建小球
			createCircle(59, 28, 17, BodyType.DYNAMIC);
			createCircle(422, 130, 17, BodyType.DYNAMIC);
		}
		//创建圆形的Nape刚体
		private function createCircle(posX:Number, posY:Number, radius:int, type:BodyType):void
		{
			//创建刚体,Body有两个参数,一个是指刚体的类型,一个是指刚体的坐标
			var circle:Body = new Body(type, new Vec2(posX, posY));
			//创建刚体形状,刚体形状类型有两种:Circle或Polygon,但不代表刚体形状只有两种,Polygon类可以创建出各种形状的多边形刚体形状
			//第二个参数的Material对象,我只传入了一个参数,表示刚体的弹性系数,后续我会专门介绍material类。
			var shape:Circle = new Circle(radius, null, new Material(1));
			//刚体的shapes是一个ShapeList类型的对象,不能直接将Shape对象复制给它,要通过push,将形状添加到ShapeList中去
			circle.shapes.push(shape);
			//设置刚体的空间
			circle.space=space;
		}
		//创建矩形的Nape刚体
		private function createBox(posX:Number,posY:Number,width:Number,height:Number,type:BodyType, angle:Number=0):Body{
			//创建刚体,Body有两个参数,一个是指刚体的类型,一个是指刚体的坐标
			var box:Body = new Body(type, new Vec2(posX, posY));
			//创建刚体形状,刚体形状类型有两种:Circle或Polygon,但不代表刚体形状只有两种,Polygon类可以创建出各种形状的多边形刚体形状
			//Polygon.box()方法会返回一个保存了指定宽高的矩形4个顶点的数组,然后将这个数组传入到Polygon的第一个参数中,矩形就创建好了
			var shape:Polygon = new Polygon(Polygon.box(width, height));
			//创建一定的角度,单位是弧度
			shape.rotate(angle);
			//刚体的shapes是一个ShapeList类型的对象,不能直接将Shape对象复制给它,要通过push,将形状添加到ShapeList中去
			box.shapes.push(shape);
			//设置刚体的空间
			box.space=space;

			return box;
		}
		private function loop(event:Event):void
		{
			//Nape空间模拟
			space.step(1 / 60);
			//清除视图
			debug.clear();
			//绘制空间
			debug.draw(space);
			//优化显示视图
			debug.flush();
		}
	}
}

源代码下载

 

联系作者

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

9 Replies to “创建简单的Nape刚体”

  1. 拉登哥,我现在可以不看你代码创建space和刚体什么了,只是有一个疑点,就是坐标和注册点的关系。调了注册点后,坐标就对不上,算的有点头晕!

  2. 调试试图就是ShapeDebug,通常情况下,我们需要调试游戏,这时候可以用shapeDebug显示模拟出来的刚体形状,查看模拟效果!

  3. debug只是一个Sprite对象,所以你可以像操作其他可视对象一样,直接调整它的x,y坐标至舞台中间。
    但要注意,贴图的时候,也要偏移值舞台中间,即贴图.x=debug.x+stage.stageWidth/2;

发表回复

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