Cork

ごすらぼ!

バイクと車とゲーム開発の記録

【Box2D】剛体シミュレーションをしてみる

この記事をシェアする

f:id:gothlab:20210718064005j:plain

まとめ

  • Box2D を使用して,実際に剛体シミュレーションをしてみた

参考

今回参考にしたのは公式のドキュメント *1
コードはほぼ Hello Box2D の項目にあるものそのまま.

box2d.org

剛体シミュレーションの実装

ワールドを作成する

まずは剛体を動作させる

  • 「世界」を定義

する必要がある. *2
第一引数に重力加速度のベクトルを設定するらしい.

b2Vec2 gravity(0.0f, 10.0f);
b2World world(gravity);

これで世界を作成できる.
非常に簡単.

重力は
「今回はDXライブラリの画面上の座標 == Box2D の動作単位」
とするため,
Y 方向に +10 とした.

剛体を作成する

次に剛体の情報を設定する.
剛体情報の構造体をインスタンス化し,

  • 剛体タイプに static (動かさない)
  • 初期位置(100.0f, 200.0f)

を設定.
その情報を使って,ワールドに剛体を Create する.

b2BodyDef groundBodyDef;
groundBodyDef.position.Set(100.0f, 200.0f);
groundBodyDef.type = b2_staticBody;
b2Body* groundBody = world.CreateBody(&groundBodyDef);

次に

  • 形状を設定

し,
その後

  • 剛体と形状をリンク

させる.

b2PolygonShape groundBox;
groundBox.SetAsBox(100.0f, 20.0f);
groundBody->CreateFixture(&groundBox, 0.0f);

これで OK .

世界を更新する

最後に,
毎フレーム位置を更新するために,

  • 世界を更新する関数を呼び出す.

設定は,

  • タイムステップは1フレームあたりにすすめる時間(秒)なので1/60秒.
  • 反復回数はとりあえずサンプルコードのまま
  • ベロシティが 6,ポジションが 2 .
    • ※ 推奨は,速度が 8,位置 が 3 らしい. *3
float timeStep = 1.0f / 60.0f;
int32 velocityIterations = 6;
int32 positionIterations = 2;
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 )
{
    world.Step(timeStep, velocityIterations, positionIterations);
}

完成コード

動的ボックスも追加した完成コード.

#include "DxLib.h"
#include <box2d.h>


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    ChangeWindowMode( true );

    if( DxLib_Init() == -1 )
    {
        return -1 ;
    }

    // Box2D の使用とメインループ
    {
        b2Vec2 gravity(0.0f, 10.0f);
        b2World world(gravity);

        b2BodyDef groundBodyDef;
        groundBodyDef.position.Set(100.0f, 200.0f);

        b2Body* groundBody = world.CreateBody(&groundBodyDef);

        b2PolygonShape groundBox;
        groundBox.SetAsBox(100.0f, 20.0f);
        groundBody->CreateFixture(&groundBox, 0.0f);

        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(100.0f,8.0f);
        bodyDef.angle = (0.6f);
        b2Body* body = world.CreateBody(&bodyDef);

        b2PolygonShape dynamicBox;
        dynamicBox.SetAsBox(20.0f, 20.0f);

        b2FixtureDef fixtureDef;
        fixtureDef.shape = &dynamicBox;
        fixtureDef.density = 1.0f;
        fixtureDef.friction = 0.3f;
        body->CreateFixture(&fixtureDef);

        float timeStep = 1.0f / 60.0f;
        int32 velocityIterations = 6;
        int32 positionIterations = 2;

        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 )
        {
            world.Step(timeStep, velocityIterations, positionIterations);
        }
    }

    DxLib_End() ;               // DXライブラリ使用の終了処理

    return 0 ;               // ソフトの終了 
}

DXライブラリで可視化してみた

剛体シミュレーションの様子を DXライブラリで可視化してみた.
ちゃんと剛体シミュレーションが行われている様子が確認できる.
Git を貼っておく.
f:id:gothlab:20210720210558g:plain

なお gif の作成にはこちらを使用させていただいた.
大変便利.

syncer.jp

おわりに

物理エンジンHav○k で育った自分には大変使いやすい予感.
次回は DXライブラリでのデバッグ描画の方法をまとめる.

*1:英語読めないので goolge 翻訳をフル活用.

*2:box2d.org

*3:box2d.org