最新のBox2D環境2019

最新バージョンは2.3.0

最新のBox2D環境2016

2016年の7月現在においてBox2Dの最新情報は2015年の7月となっているようなので実に1年近く音沙汰がない。とはいえgoogle codeからgitにその公開場所を変えたようなので、コツコツ更新されているかもしれないので調べてみると大きな更新はここ数ヶ月~年単位でなさそうな感じではあるが、細かい修正は色々あるので、以前使っていた演算結果と異なる結果になることはあるかもしれない。

ApplyForceToCenter(const b2Vec2& force, bool wake)
ApplyTorque(float32 torque, bool wake)

たとえばSleep中のオブジェクトに強制的に角度を渡したりする時にAwakeしないといけなかったのが、関数呼び出しの時に指定できるようになっている。デフォルト引数の対応とかではないので、ソースコードを一部改変する必要があった。またこれにより以前と動作がかわり不自然な挙動のキャラクタが1件発見された。これは以前たまたまうまく動いていたのか、今回の仕様変更で動かなくなったのか原因は未調査。

コードの扱い方は少なくとも2015年に携わっていた経験者は2016年でも、扱いには困らないっぽい。新しいMotorジョイントができたり、限定的に演算結果を最適化したりしてる感じ。

Box2Dの組み込み

http://box2d.org/からgitを辿ってソースコードをまるごとダウンロードして、適当なディレクトリに配置。gxLib的には「src/Box2D」に配置してリコンパイルするとあっさりコンパイル完了。使い方を忘れてそうなので、おさらいがてら復習してみよう。

includeファイルはこれだけでイイ。box2dのこういうシンプルなところがとても好き。

#include "Box2D/Box2D.h"

まずはワールドの設定

物理演算を管理するWorldの設定を行う。といっても重力値を設定してb2Worldをnewするだけ。

b2Vec2 gravity( 0, 1.f );
b2World* m_pWorld = new b2World( gravity );

これでめくるめくような物理の世界の準備が完了。この物理の世界のスケール感のコツとしては0.1~10くらいの範囲で数値を扱うのが適切らしい。つまり画面の端から端まで移動しても0~10くらいの座標で扱い、キャラの大きさは小さくとも0.1くらいで使うこと。

ピクセルに換算すると、16x16のマリオを0.1として扱うとステージの終端は1600ピクセルくらいになるということである。1600ピクセルというと当時のファミコンの解像度で言うと約6.5画面分となる。実際のスーパーマリオの1-1は横に3400ピクセル程度なので、だいたいスターが出てくるアタリで1600くらいである。アレくらいのキャラの大きさとステージの大きさの限界をイメージしておくといい。それ以上にステージが大きくなったりキャラが小さくなったりしてももちろん動かすことはできるが、値が極端になると計算精度がどんどん悪くなるので注意。

物理エンジンの考え方

基本的に汎用のマルチプラットフォーム対応の物理エンジンなのでプラットフォームに依存するようなコードはない。ということはプラットフォームやプログラムごとに異なる仕組みを持つ画面に何かを表示したり、文字を表示したりする機能は「ない」ということである。サンプルには表示できる仕組みがあるが、基本的にそこはBox2Dとは関係がない。コンソール画面上で物体の動きをあくまで数学的に計算するライブラリであり、だからこそ自分のシステムに組み込みやすいのである。

gxLibでは、物理演算された結果を元に画面表示を行って動作確認したり、ゲームに組み込んでいる。

概要としてはこの物理ワールドに、任意の四角形と丸を好きな場所に好きな角度で配置できると考えてほしい。そして自分で時間を進めることで、その図形の数秒後の移動先の位置情報を取得することができる。プログラム的には「こういう四角をここに置いて、その上に四角を配置して時間をすすめて、図形から更新された位置情報と角度を取得する」というイメージ。
 
その時の図形に重さや反射率などのプロパティ(fixtureと呼ばれる)を設定することで図形が衝突した時の反射場所が変わる。その時にプロパティで「static」に設定したオブジェクトは「動かないオブジェクト」として障害物や床に設定することができる。
 
その他、便利なのは、各オブジェクトを「ジョイント」と呼ばれる要素でつなぐことができることで、チェーン的なつながりや滑車などを再現できる。
 
あとよく使うのはグループを設定して、当たり判定を取るものと取らないものの仲間を設定できる。つまり「自機のショットは自機とは判定を取らないけれども、敵とは判定を行う」といったカテゴリわけである。少しくせがあるのでなれるのに苦労するが考え方はシンプルである。

多角形も扱えるよ

あと、凹型にならなければ、自分で多角形を設定できる。ただし(デフォルトで)渡せる頂点の数は決まっているので、超複雑な多角形は描けない。ソースのMAX頂点数を変更すれば頂点数を増やすことはできる。

基本的にはできるだけ単純な多角形を作って各キャラごとに適当な図形に当てはめて物理演算するのがシンプルでオススメ。四角形や三角形と言っても、キャラや、キャラの部位によってそれぞれ形はことなるので、各キャラの姿形にあわせた、それっぽい多角形をつくる、MAPは三角形と四角形、丸を駆使してマップのオブジェクトを再現。どうしても必要なところだけ多角形に頼る、といい。各オブジェクトは反時計回りの頂点設定、凹型にならない、というところに注意。

適当にFAQを勘で訳してみる

文中には補足とか経験談も入ってるので注意してね。

What is Box2D?

BOX2Dは Erin CattoによってC ++で作られた機能が豊富な2D剛体物理エンジンです。ゲーム大賞のグランプリを含む多くのゲームで使用されています。
BOX2Dはzlibライセンスを使用しており、無料で利用することができます。可能であればBOX2Dを使っていることをどこかに書いておいてBox2Dの信用を広めよう。

What platforms does Box2D support?

BOX2Dは、Visual C ++を使用してWindows上で開発されています。FlashやJava、C#、 Pythonに移植されています。
作者(Erin Catto)は、C ++バージョンを保守し、他の言語をサポートしません。他の言語は、各コミュニティによって、おそらくそれらの移植版の作者によってサポートされます。
作者は、それらの移植版からのフィードバックを受け付けてBox2Dの原動力としていきます。

How do I get help?

わからないことがあった時。
FAQの残りとドキュメントを読んでね。それと、ソースに含まれるサンプルを確認しよう。それでもわからない場合にはフォーラム
参照することができるよ。くれぐれもプライベートメッセージやメールで作者にサポートを求めないこと。フォーラムでディスカッションすることでみんなが問題を共有して
解決することの恩恵を受けられることが最善の質問方法だと思うよ。

Where is the official documentation?

マニュアルが最良の情報源だけれども、利用可能なドキュメントがたくさんあります。マニュアルはディストリビューション毎にここにあります

Why isn't feature foo documented?

If you grab the latest code from the SVN trunk you will likely find features that are not documented in the manual. New features are added to the manual after they are mature and a new point release is imminent. However, all major features added to Box2D are accompanied by example code in the testbed to test the feature and show the intended usage.

Prerequisites

Programming

You should have a working knowledge of C++ before you use Box2D. You should understand classes, inheritance, and pointers. There are plenty of resources on the web for learning C++. You should also understand your development environment: compilation, linking, and debugging.

Math and Physics

You should have a basic knowledge of rigid bodies, force, torque, and impulses. If you come across a math or physics concept you don't understand, please read about it on Wikipedia. Visit this page if you want a deeper knowledge of the algorithms used in Box2D.

API

What units does Box2D use?

Box2D is tuned for meters-kilograms-seconds (MKS). Your moving objects should be between 0.1 - 10 meters. Do not use pixels as units! You will get a jittery simulation.

How do I convert pixels to meters?

Suppose you have a sprite for a character that is 100x100 pixels. You decide to use a scaling factor that is 0.01. This will make the character physics box 1m x 1m. So go make a physics box that is 1x1. Now suppose the character starts out at pixel coordinate (345,679). So position the physics box at (3.45,6.79). Now simulate the physics world. Suppose the character physics box moves to (2.31,4.98), so move your character sprite to pixel coordinates (231,498). Now the only tricky part is choosing a scaling factor. This really depends on your game. You should try to get your moving objects in the range 0.1 - 10 meters, with 1 meter being the sweet spot.

Why don't you use this awesome C++ feature?

Box2D is designed to be portable, so I try to keep the C++ usage simple. Also, I don't use the STL (except sort) or other libraries to keep the dependencies low. I keep template usage low and don't use name spaces. Remember, just because a C++ feature exists, that doesn't mean you need to use it.

The many ports of Box2D to other languages platforms shows that this strategy has been successful.

Can I use Box2D in a DLL?

Box2D was not designed to be used in a DLL. You may have to change how static data is used to make this work.

Is Box2D thread-safe?

No. Box2D will likely never be thread-safe. Box2D has a large API and trying to make such an API thread-safe would have a large performance and complexity impact.

Build Issues

Why doesn't my code compile and/or link?

There are many reasons why a build can go bad. Here are a few that have come up:

   Using old Box2D headers with new code
   Not linking the Box2D library with your application
   Using old project files that don't include some new source files

Rendering

What are Box2D's rendering capabilities?

Box2D is only a physics engine. How you draw stuff is up to you.
But the Testbed draws stuff

Visualization is very important for debugging collision and physics. I wrote the test bed to help me test Box2D and give you examples of how to use Box2D. The TestBed is not part of the Box2D library.
How do I draw shapes?

Drawing shapes is not supported and shape internal data is likely to change. Instead you should implement the b2DebugDraw interface.

Accuracy

Box2D uses approximate methods for a few reasons.

   Performance
   Some differential equations don't have known solutions
   Some constraints cannot be determined uniquely

What this means is that constraints are not perfectly rigid and sometimes you will see some bounce even when the restitution is zero. Box2D uses Gauss-Seidel to approximately solve constraints. Box2D also uses Semi-implicit Euler to approximately solve the differential equations. Box2D also does not have exact collision. Polygons are covered with a thin skin (around 0.5cm thick) to avoid numerical problems. This can sometimes lead to unexpected contact normals. Also, some shapes may begin to overlap and then be pushed apart by the solver.

Making Games

Worms Clones

Making a worms clone requires arbitrarily destructible terrain. This is beyond the scope of Box2D, so you will have to figure out how to do this on your own.

Tile Based Environment

Using many boxes for your terrain may not work well because box-like characters can get snagged on internal corners. A future update to Box2D should allow for smooth motion over edge chains. In general you should avoid using a rectangular character because collision tolerances will still lead to undesirable snagging.

For more information see this post: http://box2d.org/forum/viewtopic.php?f=3&t=3048

Asteroid Type Coordinate Systems

Box2D does not have any support for coordinate frame wrapping. You would likely need to customize Box2D for this purpose. You may need to use a different broad-phase for this to work.

Determinism(正確性)

Is Box2D deterministic?

FAQからもう一つ。正確性について。
Box2Dを使った計算においては、別のプラットフォーム、システム上で同じ計算結果が出るとは限らないことを頭に入れておこう。Box2Dでは計算の基礎にランダムが絡むような
要素を入れているわけではないが、各システムにおいて浮動小数点演算の取り扱い方が異なるため、必ずしも同じ結果が出るとは限らない。
これはつまりCocos2Dなどでマルチプラットフォーム対応を行った場合でも同様で、macとWindowsで同じ計算結果にならなかもしれない。ということは、macで作ったリプレイ機能や通信対戦において別の計算結果が算出されることにより、同期できない(違った結果になる)ということである。もっと簡単に言うと、アングリーバードをiOSでプレイした時と、全く同じプレイをWindowsで再現した時に、オブジェクトの崩れ方に違いが出てクリアできるステージもクリアができなくなってしまう可能性がある、ということである。

But I really want determinism

とはいえ、プラットフォームに依存しない結果にしたいのはヤマヤマではある。過去にニンテンドーDS用に固定小数点を使ったものが移植されたことがあるらしく、それは問題なかったが、
固定小数点演算は遅く、開発するのがより面倒なのでBOX2Dのために固定小数点を使用しないことを採択した、らしい。

Why is the restitution/friction mixing inaccurate?

あと、衝突による正確な反発値には期待しないでね。同時に衝突するものを増やすほど精度が悪化するよ。計算結果を都合良く丸めるにはb2Settingを利用してください。とある。
要はビリヤードのブレイクショットなどで先頭の球から連鎖して全ボールへ衝突が波及するような場合に精度がどんどんわるくなる、ということだと思われる。
あくまで物理シミュレーションをゲームで手軽にあつかえる高速なライブラリなんです、というところを意識しておこう。

What are the biggest mistakes made by new users?

とりあえず、FAQにある初心者のありがちなミス。

  • 長さの単位にメートルではなくピクセルを使ってしまう
  • box2Dの動作でピクセル単位の計算結果を期待してしまう
  • b2Polygonを使用した凹型ポリゴンを作ってしまう
  • Releaseモードでプログラムを試しちゃう
  • C++を知らずにBox2Dにチャレンジしてしまう
  • FAQを読んでいない

メートルではなくピクセルを使ってしまってはいけない、というのは例えば、32x32ピクセルの自機に対して、Box2Dに大きさを32m x 32mで設定してしまうような場合を指すと思われる。
Box2Dにおいて

C++の知識は当然いるし、プロジェクトの設定やビルド方法、デバッグの知識も最低限必要とあるが、これほど簡単に物理が扱えるライブラリは他にないのであわせて
FAQもぜひ読んでおこう。