Nape中的LineJoint-线段关节
今天要学习的内容时LineJoint线段关节,通过线段关节,我们可以限制刚体在某个指定的方向上来回移动。就像算珠只能在算盘的轴上移动一样。
老规矩,我们先来看一下LineJoint的构造函数:
public function LineJoint( body1:Body, body2:Body, anchor1:Vec2, anchor2:Vec2, direction:Vec2, jointMin:Number, jointMax:Number):void
每个参数的作用说明如下:
- body1:和其他的关节一下,关节连接的第1个刚体
- body2:和其他的关节一下,关节连接的第2个刚体
- anchor1:连接刚体body1的节点,其坐标是相对于body1的本地坐标的
- anchor2:连接刚体body2的节点,其坐标是相对于body2的本地坐标的
- direction:线段关节中线条的方法,用一个Vec2向量表示
- jointMin:线段上沿direction方法,距离anchor1的距离
- jointMax:线段沿上direction方向,距离anchor2的距离
看完构造函数和参数说明,依然有些不知其解,看看下面的图示会更简单些:
如图所示,anchor1和anchor2是线段关节中的两个点,两点形成的线段即线段关节。线段关节的方向可以用anchor1.sub(anchor2)表示。线段起点与anchor1的距离是JointMin,终点与anchor1的距离是jonitMax;jointMin/jointMax小于0,在anchor1左侧,大于0在anchor1右侧。值得注意的是,body1可不能绕着anchor1旋转,而body2可以绕着anchor2旋转。
还记得distanceJoint示例吗?如果把示例中的刚体限制在水平方向移动,会是什么样子呢?下面的示例中,点击圆形刚体,可以在水平方向拖动,它通过一个distanceJoint关节与下面的矩形刚体连接。按下空格键”剪断”这个distanceJoint关节,让矩形落到下面的圆形范围内。有没有《割绳子》游戏里的样子呢?赶快动手试试吧!
[swfobject]852[/swfobject]
完整的代码和注释如下:
package learnNape { import ldEasyNape.LDEasyUserData; import com.bit101.components.PushButton; import nape.callbacks.InteractionCallback; import nape.callbacks.InteractionType; import nape.callbacks.CbEvent; import nape.callbacks.InteractionListener; import nape.callbacks.CbType; import flash.ui.Keyboard; import flash.events.KeyboardEvent; import nape.constraint.DistanceJoint; import nape.shape.Circle; import flash.events.MouseEvent; import nape.constraint.LineJoint; import ldEasyNape.LDEasyNape; import nape.phys.Body; import nape.geom.Vec2; import learnNape.AbstractNapeTest; /** * @author yangfei */ [SWF( width="400", height="500", frameRate="60")] public class T19_LineJoint extends AbstractNapeTest { private var anchorX1 : Number = 100; private var anchorX2 : Number = 300; private var anchorY1 : Number = 100; private var anchorY2 : Number = 300; private var anchorBody1 : Body; private var anchorBody2 : Body; private var joint1 : LineJoint; private var joint2 : LineJoint; private var distanceJoint : DistanceJoint; private var box : Body; private var sensorType : CbType; private var boxType : CbType; private var graphic : LDEasyUserData; public function T19_LineJoint() { super(); } override protected function onNapeWorldReady() : void { createStuff(); var sensorListener : InteractionListener = new InteractionListener(CbEvent.BEGIN, InteractionType.SENSOR, sensorType, boxType, onCollision); napeWorld.listeners.add(sensorListener); new PushButton(this, 280, 15, "reStart",function (e:MouseEvent):void{ box.position.setxy(anchorBody1.position.x+10, anchorY1-50); distanceJoint.body1= anchorBody1; distanceJoint.body2 = box; distanceJoint.active = true; }); } private function createStuff():void{ var sensorShape : Circle = new Circle(50); sensorShape.sensorEnabled = true; sensorType = new CbType(); graphic = new LDEasyUserData(); graphic.setGraphicAuotmatically(0); //创建上面的圆形刚体 anchorBody1 = LDEasyNape.createCircle(anchorX1, anchorY1, 10, false, false, graphic); anchorBody1.shapes.add(sensorShape); anchorBody1.cbTypes.add(sensorType); //用线段关节限制anchorBody1只能在水平方向移动 var anchorStart1 : Vec2 = new Vec2(anchorX1, anchorY1); var anchorEnd1 : Vec2 = new Vec2(anchorX2, anchorY1); var direction1 : Vec2 = anchorEnd1.sub(anchorStart1); joint1 = new LineJoint(napeWorld.world, anchorBody1, anchorStart1, Vec2.weak(), direction1, 0, direction1.length); joint1.space = napeWorld; //创建下面的刚体 anchorBody2 = LDEasyNape.createCircle(anchorX2, anchorY2, 10, false, false, graphic.clone()); anchorBody2.shapes.add(sensorShape.copy()); anchorBody2.cbTypes.add(sensorType); //用线段关节限制anchorBody1只能在水平方向移动 var anchorStart2 : Vec2 = new Vec2(anchorX1, anchorY2); var anchorEnd2 : Vec2 = new Vec2(anchorX2, anchorY2); var direction2 : Vec2 = anchorEnd2.sub(anchorStart2); joint2 = new LineJoint(napeWorld.world, anchorBody2, anchorStart2, Vec2.weak(), direction2, 0, direction2.length); joint2.space = napeWorld; graphic.setGraphicAuotmatically(0xFF0000,1); box = LDEasyNape.createBox(anchorX1+10, anchorY1-50, 30, 30, false, false, graphic.clone()); boxType = new CbType(); box.cbTypes.add(boxType); //创建距离关节,连接矩形和圆形 distanceJoint = new DistanceJoint(anchorBody1, box, Vec2.weak(), Vec2.weak(), 0, 100); distanceJoint.space = napeWorld; } private function onCollision(cb: InteractionCallback):void{ var anchorBody : Body = cb.int1.castBody; if(!anchorBody.constraints.has(distanceJoint)){ distanceJoint.body1 = anchorBody; distanceJoint.body2 = box; distanceJoint.active = true; } } override protected function mouseEventHanlder(event : MouseEvent) : void { if(event.type == MouseEvent.MOUSE_DOWN){ if(LDEasyNape.getBodyAtMouse()!=null ){ if(LDEasyNape.getBodyAtMouse().shapes.length<=1) return; } } super.mouseEventHanlder(event); } override protected function keyBoardEventHanlder(event : KeyboardEvent) : void { if(event.type != KeyboardEvent.KEY_DOWN) return; if(event.keyCode == Keyboard.SPACE){ if(box.constraints.length>0){ box.constraints.at(0).active = false; } } } } }
点击下载源文件
联系作者