用Body.graphic属性实现Nape刚体贴图

首先向一直以来关注ladeng6666的网友道个歉,最近一直赶稿子,没及时更新教程,非常抱歉,今天我们继续学习Nape。

前两天,天地会论坛里有兄弟问道Nape刚体怎么贴图,作为一个负责任的大叔,就应该及时满足大家的需求,所以今天我们就来学习Nape刚体贴图。

还记得Box2D里的刚体贴图是怎么实现的吗?忘记啦!正好,又是b2Shape又是b2Fixture的,Box2D确实挺麻烦的,直接学习Nape反倒更容易理解一些。

Nape可以通过Body刚体的graphics属性简单快速的设置刚体贴图,就像Flash中的Graphics对象一样,Sprite里绘制的原生图形不也是绘制在Graphics属性里的嘛。(如果你不了解这些Flash这些绘图内容,没关系,敬请期待拉登大叔翻译的《ActionScript 3.0 Image Effects》吧!)

下面我们通过代码来看看实现的过程吧:

		var box:Body = new Body(BodyType.STATIC, new Vec2(posX, posY));
		var userData:Sprite = new Sprite();
		box.graphic=userData;

代码中创建好box刚体之后,创建了一个名为userData的Sprite对象,作为刚体的贴图(不过Sprite里什么都没有,稍后我们会绘制一些图形在里面)。然后将userData赋值给box刚体的graphic属性,这样刚体贴图就完成了。Nape会根据刚体的坐标和角度实时的更新贴图的坐标和角度,让二者保持一致。

要注意的一点是,Nape在更新贴图坐标时,是更加贴图注册点更新的。因为Nape刚体的注册点是在中心位置,所以要确保贴图对象的注册点也在中心位置,否则在Nape模拟的过程中,会出现贴图偏位的现象。通过下面的图示,可以更好理解一些。

图中方框表示Nape刚体,半透明的矩形表示贴图对象。上面是图示中,贴图的注册点在中心,刚体旋转后的效果是我们希望的。而下图中,贴图的注册点在左上角,刚体旋转后就会出现贴图偏位的现象。

face_center

 

你可能会想,我在addChild时,把贴图往左上角调整一下不就行了嘛。实际上Nape跟Box2D不一样,在Box2D中,贴图的坐标是有开发者遍历刚体的坐标后,自己手动设置的,代码如下:

			for (var body:b2Body = world.GetBodyList(); body; body=body.GetNext()) {
				if (body.GetUserData() != null) {
					//根据刚体的坐标个角度,更新绑定的userData
					body.GetUserData().x = body.GetPosition().x * 30;
					body.GetUserData().y = body.GetPosition().y * 30;
					body.GetUserData().rotation = body.GetAngle() * 180 / Math.PI;
				}
			}

所以你可能会想到在这里纠正贴图坐标。但是Nape的规则很简单,就是根据贴图的注册点更新它的坐标和角度。所以我们的解决方法,就是把帖的注册点放在中心位置。

就没有别的方法了吗?当然有了,Luca Deltodesco早就想到这个问题了,所以他在Body类中设置了一个graphicOffset属性,它是一个Vec2向量,表示贴图与刚体完全匹配时,贴图注册点与刚体注册点之间的偏移量,所以上面图示中的第二种情况,应该用下面的代码来纠正:

		var box:Body = new Body(BodyType.STATIC, new Vec2(posX, posY));
		var userData:Sprite = new Sprite();
		box.graphic = userData;
		box.graphicOffset = new Vec2( -userData.width / 2, -userData.height / 2);

好了,Nape刚体贴图要讲的就这么多了,下面我把运行时绘制Nape刚体里的示例加上了贴图,点击舞台并拖动鼠标绘制矩形,同时按下shift绘制5边形,同时按下ctrl绘制圆形。

[swfobject]742[/swfobject]

主文档类的代码基本没有变,主要的变更在AbstractNapeTest类中,以createBox()方法为例,参数中增加了一个userData参数,然后在函数体中设置刚体的graphic属性:

		//创建矩形刚体,之前我们都已经讲过
		protected function createBox(posX:Number, posY:Number, w:Number, h:Number, isStatic:Boolean=false, userData:DisplayObject=null):void{
			var box:Body;
			if(isStatic){
				box = new Body(BodyType.STATIC, new Vec2(posX, posY));
			}else{
				box = new Body(BodyType.DYNAMIC, new Vec2(posX, posY));
			}
			if(userData!=null){
				box.graphic=userData;
				box.graphicOffset=box.position.mul(-1);
			}
			var boxShape:Polygon=new Polygon(Polygon.box(w,h), Material.glass());
			box.shapes.push(boxShape);
			box.space= napeWorld;
		}

 源文件下载地址

联系作者

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

5 Replies to “用Body.graphic属性实现Nape刚体贴图”

回复 斯樵

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