motor joint

昨天我们学习了 Box2D 的"距离关节"b2DistanceJoint ,并用它模拟了一个简单的自行车。今天我们来学习"马达关节" b2RevoluteJoint 。

"马达关节"b2RevoluteJoint同样连接了两个刚体bodyA和bodyB。不过和"马达关节"不同的是,它只有一个节点anchor,所以两个刚体都只能围绕这一个节点选择。另外,我们可以在这个节点anchor位置施加一个作用力maxMotorTorque,这样节点就会想马达一样转起来,所以我把它叫做"马达关节"。

还是不好理解,对吧!那就再打个比方,我把b2RevoluteJoint关节比作....电风扇。风扇叶是bodyA,马达是anchor,底座是bodyB,下面的图可以更好的解释这一点:

taishan.jpg 
如上图所示,因为节点anchor在bodyA的圆心处,所以bodyA会围绕着节点anchor旋转。

b2RevoluteJoint的initialize方法结构如下:
  1.     public function Initialize(
  2.         bA:b2Body,
  3.         bB:b2Body,
  4.         anchor:b2Vec2
  5.     ) : void
复制代码
bA即bodyA,bB即bodyB,anchor即节点,具体的功能,我在前面都讲过了,就不再赘述了。
另外,如前面提到的,通过设置b2RevoluteJointDef的maxMotorTorque、motorSpeed和enableMotor,可以模拟马达旋转。这三个参数的作用分别如下:
  • enableMotor:决定是否使用
  • motormotorSpeed:设置最大的角速度
  • maxMotorTorque:要达到角速度应用的扭矩力这三个属性是让节点转起来的必要条件,缺一不可!记住哦。

用b2RevoluteJoint实现风扇的效果如下:

完整的代码和注释如下:
  1. package
  2. {
  3.     import Box2D.Collision.Shapes.b2PolygonShape;
  4.     import Box2D.Collision.Shapes.b2Shape;
  5.     import Box2D.Common.Math.b2Vec2;
  6.     import Box2D.Dynamics.b2Body;
  7.     import Box2D.Dynamics.b2BodyDef;
  8.     import Box2D.Dynamics.b2FixtureDef;
  9.     import Box2D.Dynamics.b2World;
  10.     import Box2D.Dynamics.Joints.b2RevoluteJoint;
  11.     import Box2D.Dynamics.Joints.b2RevoluteJointDef;
  12.     import flash.display.Sprite;
  13.     import flash.events.Event;
  14.     import flash.events.MouseEvent;
  15.     import flash.geom.Point;

  16.     /**
  17.      * http://www.ladeng6666.com
  18.      * @author ladeng6666
  19.      */
  20.     public class RevoluteJointTest extends Sprite
  21.     {
  22.         private var world:b2World;
  23.         private var debugSprite:Sprite;
  24.         private var bodyA:b2Body, bodyB:b2Body;
  25.         private var posA:Point, posB:Point;

  26.         public function RevoluteJointTest()
  27.         {
  28.             LDEasyBox2D.stage = stage;
  29.             world=LDEasyBox2D.createWorld();
  30.             debugSprite=LDEasyBox2D.createDebug(world);
  31.             addChild(debugSprite);

  32.             //创建地面,
  33.             LDEasyBox2D.createWrapWall(world, stage);
  34.             createBodies();

  35.             createRevoluteJoint();

  36.             addEventListener(Event.ENTER_FRAME, loop);
  37.             stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
  38.             stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
  39.         }

  40.         private function createRevoluteJoint():void
  41.         {
  42.             //创建马达关节需求
  43.             var revoluteJoint:b2RevoluteJointDef = new b2RevoluteJointDef();
  44.             //用bodyA、bodyB和anchor节点初始化马达关节
  45.             revoluteJoint.Initialize( bodyA, bodyB, new b2Vec2(posA.x / 30, posA.y / 30));
  46.             //设置连接的两个刚体之间不进行碰撞检测
  47.             revoluteJoint.collideConnected = false;
  48.             //开启马达
  49.             revoluteJoint.enableMotor = true;
  50.             //设置马达的最大角速度,单位为 弧度/秒,如设置为Math.PI,即每秒钟转180度
  51.             revoluteJoint.motorSpeed = Math.PI;
  52.             //设置最大的扭力值
  53.             revoluteJoint.maxMotorTorque = 500;
  54.             //创建马达关节
  55.             world.CreateJoint(revoluteJoint);
  56.         }
  57.         //创建bodyA和bodyB刚体
  58.         private function createBodies():void
  59.         {
  60.             //设置两个刚体的坐标位置
  61.             posA = new Point(275, 100);
  62.             posB = new Point(275, 300);
  63.             //创建一个十字刚体,赋值给bodyA
  64.             var bodyDef:b2BodyDef = new b2BodyDef();
  65.             bodyDef.type = b2Body.b2_dynamicBody;
  66.             bodyDef.position.Set(posA.x / 30, posA.y / 30);
  67.             bodyA = world.CreateBody(bodyDef);
  68.             //设置刚体属性
  69.             var fixtureDef:b2FixtureDef = new b2FixtureDef();
  70.             fixtureDef.density = 3;
  71.             fixtureDef.restitution = .2;
  72.             fixtureDef.friction = .2;

  73.             //设置刚体形状,并赋值给fixtureDef
  74.             //一个横着的矩形
  75.             var shape:b2PolygonShape = new b2PolygonShape();
  76.             shape.SetAsBox(50/30, 5/30);
  77.             fixtureDef.shape = shape;
  78.             bodyA.CreateFixture(fixtureDef);
  79.             //加一个竖着的矩形
  80.             shape.SetAsBox(5 / 30, 50 / 30);
  81.             fixtureDef.shape = shape;
  82.             //生成刚体bodyA的形状
  83.             bodyA.CreateFixture(fixtureDef);

  84.             //创建bodyB刚体
  85.             bodyB = LDEasyBox2D.createBox(world, posB.x, posB.y, 200, 50);
  86.         }

  87.         private function onStageMouseDown(e:MouseEvent):void
  88.         {
  89.             var dragBody:b2Body = LDEasyBox2D.getBodyAtMouse(world);
  90.             if (dragBody != null) {
  91.                 LDEasyBox2D.startDragBody(world,dragBody,10000*dragBody.GetMass());
  92.             }

  93.         }

  94.         private function onStageMouseUp(e:MouseEvent):void
  95.         {
  96.             LDEasyBox2D.stopDragBody(world);
  97.         }

  98.         private function loop(e:Event):void
  99.         {
  100.             LDEasyBox2D.updateWorld(world);

  101.         }

  102.     }

  103. }
复制代码
代码中用到了我写的静态类LDEasyBox2D,可以有效的简化代码,具体请参考 这里

点击刚体,还可以进行拖动,如果对鼠标拖动刚体,我建议你看看之前的 让刚体听我的——鼠标拖动刚体 。  OK 2012-08-28 b2RevoluteJoint关节.rar (340.1 KB, 下载次数: 106) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值