天天看點

motor joint

昨天我們學習了 Box2D 的"距離關節"b2DistanceJoint ,并用它模拟了一個簡單的自行車。今天我們來學習"馬達關節" b2RevoluteJoint 。

"馬達關節"b2RevoluteJoint同樣連接配接了兩個剛體bodyA和bodyB。不過和"馬達關節"不同的是,它隻有一個節點anchor,是以兩個剛體都隻能圍繞這一個節點選擇。另外,我們可以在這個節點anchor位置施加一個作用力maxMotorTorque,這樣節點就會想馬達一樣轉起來,是以我把它叫做"馬達關節"。

還是不好了解,對吧!那就再打個比方,我把b2RevoluteJoint關節比作....電風扇。風扇葉是bodyA,馬達是anchor,底座是bodyB,下面的圖可以更好的解釋這一點:

motor joint

如上圖所示,因為節點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.     public class RevoluteJointTest extends Sprite
  17.     {
  18.         private var world:b2World;
  19.         private var debugSprite:Sprite;
  20.         private var bodyA:b2Body, bodyB:b2Body;
  21.         private var posA:Point, posB:Point;
  22.         public function RevoluteJointTest()
  23.         {
  24.             LDEasyBox2D.stage = stage;
  25.             world=LDEasyBox2D.createWorld();
  26.             debugSprite=LDEasyBox2D.createDebug(world);
  27.             addChild(debugSprite);
  28.             //建立地面,
  29.             LDEasyBox2D.createWrapWall(world, stage);
  30.             createBodies();
  31.             createRevoluteJoint();
  32.             addEventListener(Event.ENTER_FRAME, loop);
  33.             stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
  34.             stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
  35.         }
  36.         private function createRevoluteJoint():void
  37.         {
  38.             //建立馬達關節需求
  39.             var revoluteJoint:b2RevoluteJointDef = new b2RevoluteJointDef();
  40.             //用bodyA、bodyB和anchor節點初始化馬達關節
  41.             revoluteJoint.Initialize( bodyA, bodyB, new b2Vec2(posA.x / 30, posA.y / 30));
  42.             //設定連接配接的兩個剛體之間不進行碰撞檢測
  43.             revoluteJoint.collideConnected = false;
  44.             //開啟馬達
  45.             revoluteJoint.enableMotor = true;
  46.             //設定馬達的最大角速度,機關為 弧度/秒,如設定為Math.PI,即每秒鐘轉180度
  47.             revoluteJoint.motorSpeed = Math.PI;
  48.             //設定最大的扭力值
  49.             revoluteJoint.maxMotorTorque = 500;
  50.             //建立馬達關節
  51.             world.CreateJoint(revoluteJoint);
  52.         }
  53.         //建立bodyA和bodyB剛體
  54.         private function createBodies():void
  55.         {
  56.             //設定兩個剛體的坐标位置
  57.             posA = new Point(275, 100);
  58.             posB = new Point(275, 300);
  59.             //建立一個十字剛體,指派給bodyA
  60.             var bodyDef:b2BodyDef = new b2BodyDef();
  61.             bodyDef.type = b2Body.b2_dynamicBody;
  62.             bodyDef.position.Set(posA.x / 30, posA.y / 30);
  63.             bodyA = world.CreateBody(bodyDef);
  64.             //設定剛體屬性
  65.             var fixtureDef:b2FixtureDef = new b2FixtureDef();
  66.             fixtureDef.density = 3;
  67.             fixtureDef.restitution = .2;
  68.             fixtureDef.friction = .2;
  69.             //設定剛體形狀,并指派給fixtureDef
  70.             //一個橫着的矩形
  71.             var shape:b2PolygonShape = new b2PolygonShape();
  72.             shape.SetAsBox(50/30, 5/30);
  73.             fixtureDef.shape = shape;
  74.             bodyA.CreateFixture(fixtureDef);
  75.             //加一個豎着的矩形
  76.             shape.SetAsBox(5 / 30, 50 / 30);
  77.             fixtureDef.shape = shape;
  78.             //生成剛體bodyA的形狀
  79.             bodyA.CreateFixture(fixtureDef);
  80.             //建立bodyB剛體
  81.             bodyB = LDEasyBox2D.createBox(world, posB.x, posB.y, 200, 50);
  82.         }
  83.         private function onStageMouseDown(e:MouseEvent):void
  84.         {
  85.             var dragBody:b2Body = LDEasyBox2D.getBodyAtMouse(world);
  86.             if (dragBody != null) {
  87.                 LDEasyBox2D.startDragBody(world,dragBody,10000*dragBody.GetMass());
  88.             }
  89.         }
  90.         private function onStageMouseUp(e:MouseEvent):void
  91.         {
  92.             LDEasyBox2D.stopDragBody(world);
  93.         }
  94.         private function loop(e:Event):void
  95.         {
  96.             LDEasyBox2D.updateWorld(world);
  97.         }
  98.     }
  99. }

複制代碼 代碼中用到了我寫的靜态類LDEasyBox2D,可以有效的簡化代碼,具體請參考 這裡 。

點選剛體,還可以進行拖動,如果對滑鼠拖動剛體,我建議你看看之前的 讓剛體聽我的——滑鼠拖動剛體 。 

motor joint

OK 2012-08-28 b2RevoluteJoint關節.rar (340.1 KB, 下載下傳次數: 106) 

上一篇: sql必知必會2
下一篇: box2d關節

繼續閱讀