LoginSignup
7
9

More than 5 years have passed since last update.

Box2dWebでオブジェクトに力を加えて動かしてみる

Last updated at Posted at 2014-10-13

今回もbox2dwebやります
キーでオブジェクトをいろいろ制御します。

今回のスクリーンショットです。

スクリーンショット 2014-10-14 0.52.38.png

全ソースコードです。
キー操作をするためにjQueryも使ってます。

test.html
<canvas id="canvas" width="600px" height="420px" style="background-color:#333333;"></canvas>
<pre>
fキー力をかける
iキー衝撃を与える
vキー一定速度を与える
tキー瞬間移動させる
</pre>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>

<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  // 衝突オブジェクトの形状(円)
     ,  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(2,1);
    bodyDef.fixedRotation = true;

    var fixDef = new b2FixtureDef;
    fixDef.density = 1.0;
    fixDef.friction = 0.4;
    fixDef.restitution = .5;

    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(.5,1);

    var box = world.CreateBody(bodyDef);
    box.CreateFixture(fixDef);

    //地面
    var holderDef = new b2BodyDef;
    holderDef.type = b2Body.b2_staticBody;
    holderDef.position.Set(8, 14);

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

    var ground = world.CreateBody(holderDef);
    ground.CreateFixture(fd);


    var keydown = 0;
    // 力
    function push(c) {
        if(c==1)    
            box.ApplyForce(new b2Vec2(0,-300),  box.GetWorldCenter());
    }
    // 衝撃
    function hit(c) {
        if(c==1)    
            box.ApplyImpulse(new b2Vec2(5,0), box.GetWorldCenter());
    }
    // 速度
    function speed(c) {
        if(c==1){
            box.SetAwake(true);
            box.SetLinearVelocity(new b2Vec2(4,0));
        }
    }
    // テレポート
    function teleport(c) {
        if(c==1){
            box.SetAwake(true);
            box.SetPositionAndAngle(new b2Vec2(10,0),Math.PI/3);
        }
    }
    $(window).keydown(function(key) {
        keydown++;
        var code = key.keyCode;
        if(code == 102 || code == 70)   push(keydown); // fキー
        if(code == 105 || code == 73)   hit(keydown); // iキー
        if(code == 118 || code == 86)   speed(keydown); // vキー
        if(code == 116 || code == 84)   teleport(keydown); // tキー
    });
    $(window).keyup(function(e) {
        keydown=0;
    });


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


    // デバッグ描画の設定      
    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>

今回はBodyが回転しないように
fixedRotationフラグをtrueにして
向きを固定します

    bodyDef.fixedRotation = true;

このフラグを入れないとボックスが転んでしまうので
アクションゲームのキャラクターとかだと必須です。

今回は次の4つの制御を行ってみます
①オブジェクトに力を加える
②オブジェクトに衝撃を加える
③オブジェクトの速度を指定する
④オブジェクトの位置、向きを指定する

①ApplyForceメソッドでオブジェクトに力を加えることが出来ます。
第1引数には力ベクトル
第2引数には力を加える位置を指定します

box.ApplyForce(new b2Vec2(0,-300),  box.GetWorldCenter());

②ApplyImpulseメソッドでオブジェクトに衝撃を加えることが出来ます。
ApplyForceメソッドと引数は同じですが、
計算式が違います。
こちらは瞬間的な力を加えます

box.ApplyImpulse(new b2Vec2(5,0), box.GetWorldCenter());

③SetLinearVelocityメソッドで平行移動速度を指定します。
力を加えている訳ではないのでスリープ状態で
判定されずにめり込んだりする場合があるので
SetAwakeでアクティブにしておいた方がよいです

box.SetAwake(true);
box.SetLinearVelocity(new b2Vec2(4,0));

④SetPositionAndAngleメソッドで位置と向きの指定が出来ます。
こちらもSetAwakeしておいた方がよいです

box.SetAwake(true);
box.SetPositionAndAngle(new b2Vec2(10,0),Math.PI/3);

次回は衝突判定の取得をやります。

7
9
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
7
9