用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刚体,半透明的矩形表示贴图对象。上面是图示中,贴图的注册点在中心,刚体旋转后的效果是我们希望的。而下图中,贴图的注册点在左上角,刚体旋转后就会出现贴图偏位的现象。
你可能会想,我在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; }
源文件下载地址
联系作者
大叔,为什么我的Body类的实例没有graphics这个属性啊?
你用的是最新的SWC 2.0.3吗?作者已经把graphic属性删掉了,回头我会找出解决方案的!
拉登 想到解决方案了吗
额 好吧看到了