Siv3D での 2D 物理演算をサポートする Physics (Box2D)
Siv3D AdventCalendar 2016 の 18 日目の記事です.
概要
Siv3D に付属されている HamFramework の機能の一つに,簡易的な 2D 物理シミュレーションを実装できる「Physics」があります.以下のソースコードで玉を転がす遊びができます.
# include <Siv3D.hpp>
# include <HamFramework.hpp>
void Main()
{
CameraBox2D camera(Vec2(0, 10), 17.0);
PhysicsWorld world;
auto ground = world.createLineString(Vec2(0, 0), { Vec2(-20, 10), Vec2(-20, 0), Vec2(20, 0), Vec2(20, 10) }, none, none, PhysicsBodyType::Static)
.addLine({ Vec2(15, 20), Vec2(0, 15) })
.addLine({ Vec2(-15, 10), Vec2(0, 5) });
Array<PhysicsBody> bodies;
while (System::Update())
{
world.update();
camera.update();
{
const auto t1 = camera.createTransformer();
if (Input::MouseL.clicked)
{
bodies.push_back(world.createCircle(Mouse::PosF(), 1.0));
}
Circle(Mouse::PosF(), 1.0).drawFrame(0.05);
ground.draw();
for (const auto& body : bodies)
{
body.draw();
}
}
camera.draw();
}
}
2D ゲーム と物理演算
物理演算を活用した 2D ゲームは多く存在します.例えば,Rovio Entertainment が開発した Angry Birds は,物理演算を用いて鳥の主人公を飛ばし,敵やオブジェクトを破壊するゲームです.また Umea 大学の学生 Emil Ernerfeldt の修士論文で開発された Phun (現 Algodoo) は,お絵かき感覚で物理演算を楽しむことができるゲーム(ツール)であり,インターネット上に多くの作品が公開されています.このような物理演算を活用したゲームを作るためには,自分で物理演算用の計算をするか,Box2D や Chipmunk2D 等の物理演算ライブラリを利用する必要がありますが,どちらもソースコードが長くなる傾向がありました.そこで,2D の物理演算を簡単に楽しめる Physics の基本的な使い方を紹介します.
Box2D と Siv3D
HamFramework の Physics は,Box2D を Siv3D から利用しやすいようにまとめた機能です.Box2D とは オープンソースで開発された C++ の 2D ゲーム用物理演算ライブラリで,円形や多角形の剛体の運動や衝突判定をシミュレーションすることが可能です.(先程紹介した Angry Birds もこの Box2D を用いています.)HamFramework の Physics では Siv3D が C++ で開発されていることや,Box2D のドキュメントが豊富であることから,2D 物理演算に Box2D を採用しました.
基本的な使い方
ワールドの生成と更新
Main.cpp
# include <Siv3D.hpp>
# include <HamFramework.hpp>
void Main()
{
PhysicsWorld world;
while (System::Update())
{
world.update();
}
}
-
HamFramework.hpp
をインクルード
-
PhysicsWorld
クラスのインスタンスを作成
- メインループの中で
PhysicsWorld::update()
を呼ぶ
# include <Siv3D.hpp>
# include <HamFramework.hpp>
void Main()
{
PhysicsWorld world;
while (System::Update())
{
world.update();
}
}
HamFramework.hpp
をインクルードPhysicsWorld
クラスのインスタンスを作成PhysicsWorld::update()
を呼ぶこれにより,物理演算を行うための環境が生成されました.この時点では画面に何も表示されません.今後は,この PhysicsWorld
オブジェクトを利用して,運動や衝突判定を行う物体 PhysicsBody
の生成を行いきます.
物体の生成と描画
# include <Siv3D.hpp>
# include <HamFramework.hpp>
void Main()
{
PhysicsWorld world;
const auto ground = world.createLine(Vec2(0, 10), Line({ 0, 0 }, {640, 0 }), none, none, PhysicsBodyType::Static);
const auto ball = world.createCircle(Vec2(320, 300), Circle(100));
while (System::Update())
{
world.update();
ground.draw();
ball.draw();
}
}
-
PhysicsWorld::create***()
でPhysicsBody
オブジェクトを生成 - メインループの中で
PhysicsBody::draw()
を呼ぶ
PhysicsWorld::create***()
の *** の部分にはRect,Circleなどの Siv3D で用いられる図形の名前が入ります.引数には,
- 中央の位置
- 図形
- 物理定数(指定がない場合は none)
- フィルタ(指定がない場合は none)
- 静止するか運動するを決める
PhysicsBodyType
の順番で指定します.中央の位置はその PhysicsBody
の配置を意味します.しかし,このままでは不自然な点いくつかあります.
- 重力の方向が上に向かっている
- 物体の動きが遅い
これは,Box2D の単位がメートル単位であることや,Y 軸の方向が,上方向を正にしている事が原因で発生した現象です.(つまり上の例では,半径 100 [m] の円が高さ 290 [m] から降っている事になります.)そこで以前紹介した ham::Camera2D
機能を活用し,上記の不自然な点を解決します.
http://qiita.com/hamukun8686/items/95471335b8a0fa1d877f
Camera2D の利用
# include <Siv3D.hpp>
# include <HamFramework.hpp>
void Main()
{
PhysicsWorld world;
const auto ground = world.createLine(Vec2(0, -10), Line({ -20, 0 }, { 20, 0 }), none, none, PhysicsBodyType::Static);
const auto ball = world.createCircle(Vec2(0, 10), Circle(1));
CameraBox2D camera(Vec2(0, 0), 20);
while (System::Update())
{
camera.update();
{
const auto t1 = camera.createTransformer();
world.update();
ground.draw();
ball.draw();
}
camera.draw();
}
}
-
Camera2D
の派生クラスであるCameraBox2D
オブジェクトの作成と利用
これにより,Y 軸の正の方向は上方向になりした.また,カメラ位置や拡大率を変更できるようになりました.
今後の機能について
HamFramework の Physics 機能は Box2D の機能全体をカバーするため,今後のアップデートで新しい機能を追加していきます.具体的には,衝突時の処理を記述する方法,物体同士を接続して動かすジョイント機能などです.
まとめ
今回は 2D の物理演算をサポートする Physics の基本的な使い方について解説しました.Physics を用いたゲームが公開されることを期待しています.
明日は @Nicious さんの記事です.よろしくお願いいたします.
Author And Source
この問題について(Siv3D での 2D 物理演算をサポートする Physics (Box2D)), 我々は、より多くの情報をここで見つけました https://qiita.com/hamukun8686/items/911b9aeb73734126edea著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .