LoginSignup
2
3

More than 5 years have passed since last update.

Box2dWebの回転ジョイントで乗りものを作ってみる

Last updated at Posted at 2014-10-05

今回はbox2dwebで回転ジョイントをやります。
回転ジョイントはモーターのような役割を果たします

今回のスクリーンショットです
台車に接続された車輪が回転することで
台車が移動します

名称未設定.png

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

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 // 回転ジョイント
     ,  b2DebugDraw = Box2D.Dynamics.b2DebugDraw // デバッグ描画


    // 世界を作る
    var world = new b2World(new b2Vec2(0,10), true);

    /////////////////////////////

    var bodyDef = new b2BodyDef;
    bodyDef.type = b2Body.b2_dynamicBody;

    var fixDef = new b2FixtureDef;
    fixDef.density = 30;
    fixDef.friction = 10;
    fixDef.restitution = 0.1;
    fixDef.shape = new b2CircleShape(0.3);

    // 車輪1
    bodyDef.position.Set(8,10);
    var wheel1=world.CreateBody(bodyDef);
    wheel1.CreateFixture(fixDef);
    // 車輪2
    bodyDef.position.Set(12,10);
    var wheel2=world.CreateBody(bodyDef);
    wheel2.CreateFixture(fixDef);

    // 台車
    bodyDef.position.Set(10,9.5);
    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(4,.5);
    var car = world.CreateBody(bodyDef);
    car.CreateFixture(fixDef);

    // 回転ジョイント
    var revoluteJointDef = new b2RevoluteJointDef();
    revoluteJointDef.Initialize(car, wheel1, wheel1.GetWorldCenter());
    revoluteJointDef.maxMotorTorque = 1100.0;// トルク力
    revoluteJointDef.motorSpeed = 3.0; // 回転速度
    revoluteJointDef.enableMotor = true; // モーターを有効化
    var revoluteJointA = world.CreateJoint(revoluteJointDef);

    revoluteJointDef.Initialize(car, wheel2, wheel2.GetWorldCenter());
    revoluteJointDef.lowerAngle = -Math.PI/2; // 可動範囲の最小値
    revoluteJointDef.upperAngle = Math.PI*5; // 可動範囲の最大値
    revoluteJointDef.enableLimit = true; // 可動範囲を可動有効化
    var revoluteJointB = world.CreateJoint(revoluteJointDef);

    // 地面
    var bodyDef = new b2BodyDef;
    bodyDef.type = b2Body.b2_staticBody;
    bodyDef.position.Set(-3,14);

    var fd = new b2FixtureDef;
    fd.shape = new b2PolygonShape;
    fd.shape.SetAsBox(20,1);

    var holder = world.CreateBody(bodyDef);
    holder.CreateFixture(fd);    

    /////////////////////////////


    // デバッグ描画の設定      
    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(); // 物理世界上の力をリセットする
    };

</script>

回転ジョイント用に
b2RevoluteJointDefオブジェクトを追加します。

var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef // 回転ジョイント

回転ジョイントを作成しているのは次の箇所です。
b2RevoluteJointDefオブジェクトのInitialize関数で
ひも付けする台車オブジェクトと車輪オブジェクト、車輪の位置を指定します。
maxMotorTorqueはトルク力(パワー)です
motorSpeedはモーターの回転スピードです
enableMotorをtrueにしてモーターを回転させます

    // 回転ジョイント
    var revoluteJointDef = new b2RevoluteJointDef();
    revoluteJointDef.Initialize(car, wheel1, wheel1.GetWorldCenter());
    revoluteJointDef.maxMotorTorque = 1100.0;
    revoluteJointDef.motorSpeed = 3.0;
    revoluteJointDef.enableMotor = true;
    var revoluteJointA = world.CreateJoint(revoluteJointDef);

次は右側の車輪の設定です。
lowerAngleは可動範囲の最小値を指定します。
upperAngleは可動範囲の最大値を指定します。
enableLimitは回転の制限を有効化します
可動範囲を超えて回転させようとすると回転が止まります。

    revoluteJointDef.Initialize(car, wheel2, wheel2.GetWorldCenter());
    revoluteJointDef.lowerAngle = -Math.PI/2; // 可動範囲の最小値
    revoluteJointDef.upperAngle = Math.PI*5; // 可動範囲の最大値
    revoluteJointDef.enableLimit = true; // 可動範囲を可動有効化
    var revoluteJointB = world.CreateJoint(revoluteJointDef);

おまけその1:
b2RevoluteJointDefオブジェクトのInitialize関数のジョイント対象に
world.GetGroundBody()を指定すると
物理世界に対して固定されて回転します

revoluteJointDef.Initialize(world.GetGroundBody(), wheel1, wheel1.GetWorldCenter());

台車の台のみ押し出されます

スクリーンショット 2014-10-05 23.28.29.png

おまけその2:
途中でモーターを逆回転したい場合は
生成した回転ジョイントオブジェクトに対して
SetMotorSpeed関数でマイナスの値をいれてやると
逆回転になります

 revoluteJointA.SetMotorSpeed(-3.0);
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3