Box2dWebで開閉扉を作ってみる

最近サボり気味ですが
今回はbox2dwebでギアジョイントをやります
ギアジョイントは複数の直動ジョイントや回転ジョイントの動きを連動させます。

今回のスクリーンショットです。
円の回転運動にあわせて
ボックスをピストン運動させます

![スクリーンショット 2014-10-09 0.33.42.png](https://qiita-image-store.s3.amazonaws.com/0/55077/f63ccba8-ef1c-fa9b-458e-5ebbcb82751e.png)

今回の全ソースコードです

```js:test.html
<canvas id="canvas" width="600px" height="420px" style="background-color:#333333;"></canvas>

<script type="text/javascript" src="Box2dWeb-2.1.a.3.min.js"></script>
<script type="text/javascript">
      
    // Box2Dオブジェクトを取得
    var b2Vec2 = Box2D.Common.Math.b2Vec2 // 2Dベクトル
     ,  b2BodyDef = Box2D.Dynamics.b2BodyDef // Body定義
     ,  b2Body = Box2D.Dynamics.b2Body // Body
     ,  b2FixtureDef = Box2D.Dynamics.b2FixtureDef // Fixture定義
     ,  b2Fixture = Box2D.Dynamics.b2Fixture // Fixture
     ,  b2World = Box2D.Dynamics.b2World // 物理世界
     ,  b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape // 衝突オブジェクトの形状（ポリゴン）
     ,  b2CircleShape = Box2D.Collision.Shapes.b2CircleShape  // 衝突オブジェクトの形状（円）
     ,  b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef
     ,	b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef
     ,	b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef
     ,  b2DebugDraw = Box2D.Dynamics.b2DebugDraw // デバッグ描画
 
 
    // 世界を作る
    var world = new b2World(new b2Vec2(0,10), true);
      
    ////////////////////////////////////

    //box
    var bodyDef = new b2BodyDef;
    bodyDef.type = b2Body.b2_dynamicBody;
    bodyDef.position.Set(9,10);
		
    var fixDef = new b2FixtureDef;
    fixDef.density = 10.0;
    fixDef.friction = 0.1;
    fixDef.restitution = .5;		
    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(1,5);
		
    var box = world.CreateBody(bodyDef);
    box.CreateFixture(fixDef);
		
    //circle
    bodyDef.position.Set(4,8);
    fixDef.shape = new b2CircleShape(1);
    var wheel = world.CreateBody(bodyDef);
    wheel.CreateFixture(fixDef);
		
    //ジョイント
    var revoluteJointDef = new b2RevoluteJointDef();
    revoluteJointDef.Initialize(world.GetGroundBody(), wheel, wheel.GetWorldCenter()); 
    revoluteJointDef.maxMotorTorque = 2100.0;
    revoluteJointDef.motorSpeed = 3.0;
    revoluteJointDef.enableMotor = true;
    revoluteJoint = world.CreateJoint(revoluteJointDef);
		
    var worldAxis = new b2Vec2(0, 1);
    var prismaticJointDef = new b2PrismaticJointDef();
    prismaticJointDef.Initialize(world.GetGroundBody(), box, box.GetWorldCenter(), worldAxis);
    prismaticJointDef.lowerTranslation = -5.0;
    prismaticJointDef.upperTranslation = 2.5;
    prismaticJointDef.enableLimit = true;
    prismaticJoint = world.CreateJoint(prismaticJointDef);
	
    // ギアジョイント		 
    var gearJointDef = new b2GearJointDef();
    gearJointDef.joint1 = revoluteJoint;
    gearJointDef.joint2 = prismaticJoint;
    gearJointDef.bodyA = box;
    gearJointDef.bodyB = wheel;
    gearJointDef.ratio = 1;
    world.CreateJoint(gearJointDef);    
		 
   
    ////////////////////////////////////
 
 
    // デバッグ描画の設定      
    var debugDraw = new b2DebugDraw();
    debugDraw.SetSprite ( document.getElementById ("canvas").getContext ("2d"));
    debugDraw.SetDrawScale(30);     //描画スケール
    debugDraw.SetFillAlpha(0.3);    //半透明値
    debugDraw.SetLineThickness(1.0);//線の太さ
    debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);// 何をデバッグ描画するか
    world.SetDebugDraw(debugDraw);
      
    window.setInterval(update,1000/60);
      
    function update() {
        world.Step(1 / 60, 10, 10); // 物理世界を更新する
        world.DrawDebugData(); // デバック描画
        world.ClearForces(); // 物理世界上の力をリセットする
        
        if(box.GetPosition().y <= 7){
            box.SetPosition(new b2Vec2(box.GetPosition().x,10));
        }
    }
      
</script>
```

簡略のため、b2GearJointDefオブジェクトを定義しておきます

```
var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef;
```

回転ジョイント（b2RevoluteJointDef）と直動ジョイント（b2PrismaticJointDef）は
[その１６](http://qiita.com/teradonburi/items/72ca1409e1c1993e0622)と[その１７](http://qiita.com/teradonburi/items/617d861d7a441d07f15c)
で説明済みなので説明省略します
ギアジョイントで回転ジョイント、直動ジョイント
連動するBodyを指定します
ratioは動く方向です。
負の値を入れるとピストンの動く方向が逆転します

```
    // ギアジョイント		 
    var gearJointDef = new b2GearJointDef();
    gearJointDef.joint1 = revoluteJoint;
    gearJointDef.joint2 = prismaticJoint;
    gearJointDef.bodyA = box;
    gearJointDef.bodyB = wheel;
    gearJointDef.ratio = 1;
    world.CreateJoint(gearJointDef); 
```` 

次回はマウスジョイントをやります。