そもそも、私は比較的最近gamedevを扱ってきました。
したがって、コードと情報の品質に依存しないでください%)
この記事では、プロトタイプを例として使用して、Box2D物理エンジンをゲームに使用する方法について説明します。
幸運で記事が気に入ったら、第2部と第3部の両方があります。 最後に、 このようなゲームを取得します。 (はい、ゲームはひどく未完成で、記事と同じですが、グラフィックとセンサーのみがあります)
残りはカットの下にあります。
キャンプに行く
何が必要ですか?
- Box2D物理エンジン自体。 より安定しているため、バージョンが2.0.2であることが重要です。 はい、そしてそれらは同じパフォーマンスを持っています。
ここまたはここからダウンロードできます(ただし、2番目のリンクにはこのソースコードもすべて含まれています)。 - as3で何かを作成した経験が必要です。
- 実際に私たちが書くもの、言い換えれば、IDE。 ちなみに、FlashDevelop(私のように)は無料で使用できます。 または、例えばAdobe Flash CS5を使用します。
-
それぞれbrain.dllおよびhands.dll
背景
そのため、Box2Dは無料のオープンソースの2次元物理エンジン(ゲームだけでなく、ゲームでの物理世界のモデリング用)であり、C ++のためにErin Cattoによって開発されました。
しかし、Flashを使用してFlashに移植した別の良い人がいました。
誰かが、彼が非常に「太っている」と言います。例えば、ゆっくりと働く、誰か-逆に。 私は1つのことを知っています-彼らはそれで実際のゲームを作ります、したがって、おそらく、それは手に依存しています。
しかし、最初に、Box2Dに関する一般的な規定について説明する必要があります。 これらの規定は、要約の形式で提供されます。
- 測定単位としてBox2D はピクセルを使用しません
- 測定単位としてBox2D は国際システムC(si)-メートル、キログラム、秒(ISS)を使用します
- Box2Dは、10センチメートルから10メートルの範囲の動的オブジェクトで動作するように構成されました。つまり、ガラスからバスまでのオブジェクトを作成できます。
- Box2Dが動作する単位は画面の単位(ピクセル)と一致しないため、メートル(単位)の変換係数をピクセルに設定する必要があります。 たとえば、10センチ= 30ピクセルと指定できます。
- Box2Dは、動的および静的の2種類のオブジェクトで動作します
- 動的オブジェクトは、それら自体(レンガ、ボール、分子、ヘリコプター、車、人など)間の衝突の分析に関与します。静的-いいえ(地球、基礎、フレーム-絶対に破壊できないもの)
- Box2Dは、次の図との衝突を実装します:円、正方形、凸多角形。
- Box2Dのほとんどの構造の名前は、エンジンの構造を視覚的に強調し、ユーザー構造と競合する可能性を少なくするために、接頭辞「b2」で始まります。
さて、今のところ。
悪意を持ち始める
プロジェクトを作成します。ウィンドウサイズは500x500、30FPSです。クラスMain.asを探しています。
Box2Dを使用して、パパのクラスMainにこだわります。
必要なものをインポートします。
import Box2D.Dynamics.*; import Box2D.Dynamics.Joints.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*;
定数を作成します。
public static const ITERATIONS:int = 20; public static const TIMESTEP:Number = 1.0 / 30.0;
これらの定数は何ですか-後で説明します。
変数world、sprite、rotator、hero、boundsWorldを宣言します。
public var world:b2World; public var sprite:Sprite; // " " public var boundsWorld:b2Body; public var hero:b2Body; public var rotator:Number;
関数を作成します。
public function InitializePhysicsWorld():void { var worldAABB:b2AABB = new b2AABB(); // , , . worldAABB.lowerBound.Set(-300, -300.0); worldAABB.upperBound.Set(300.0, 300.0); world = new b2World(worldAABB, new b2Vec2(0, 0), false); // , worldAABB - ; new bVec2(0, 0) - , ; false - . var dbgDraw:b2DebugDraw = new b2DebugDraw(); // , , , . dbgDraw.m_sprite= sprite; dbgDraw.m_drawScale= 30; dbgDraw.m_alpha = 1; dbgDraw.m_fillAlpha = 0.5; dbgDraw.m_lineThickness = 1; dbgDraw.AppendFlags(b2DebugDraw.e_shapeBit); // world.SetDebugDraw(dbgDraw); }
そして、メイン()に次のように記述します。
public function Main():void { sprite = new Sprite(); addChild(sprite); sprite.x = sprite.y = 250; rotator = 0; InitializePhysicsWorld(); }
私たちの世界が作成されました。今度は、
世界の境界を作成し、関数を作成します。
public function CreateBoundsWorld():b2Body { var body:b2Body; // var bodyDef:b2BodyDef; // var polygon:b2PolygonDef; // bodyDef = new b2BodyDef(); polygon = new b2PolygonDef(); bodyDef.position.Set(0, 0); // x:0, y:0 polygon.density = 0; // 0, .. density , . polygon.friction = 1.0; polygon.restitution = 0.2; body = world.CreateBody(bodyDef); // // polygon.SetAsOrientedBox(300/2/30, 1/2/30, new b2Vec2(0, -300/2/30), 0); body.CreateShape(polygon); polygon.SetAsOrientedBox(300/2/30, 1/2/30, new b2Vec2(0, 300/2/30), 0); body.CreateShape(polygon); polygon.SetAsOrientedBox(1/2/30, 300/2/30, new b2Vec2(300/2/30, 0), 0); body.CreateShape(polygon); polygon.SetAsOrientedBox(1/2/30, 300/2/30, new b2Vec2(-300/2/30, 0), 0); body.CreateShape(polygon); body.SetMassFromShapes(); // , . return body; // . }
main()の最後に書き込みます:
boundsWorld = CreateBoundsWorld();
今、私たちの世界は空ではありませんが、待ってください、コンパイル時に何も見えないのはなぜですか?
怖がらないでください、親愛なるユーザー名%、すべてが順調です。 エンジンに物理学を描画させて計算させましょう。
これを行うには、関数を作成します。
public function enterFrameListener(event:Event):void { world.Step(timestep, ITERATIONS); // Box2D ( ). : Box2D Step(float timeStep,int iterations), : , . }
main()でリスナーをハングさせます:
this.addEventListener(Event.ENTER_FRAME, enterFrameListener);
起動して見る:
すべてうまくいきますが、今度は動的オブジェクトを追加するときです。この場合はヒーローボールです。 再び関数を作成します:
public function CreateHero(x:Number, y:Number):void { var bodyDef:b2BodyDef; var circleDef:b2CircleDef; var x:Number; var y:Number; var r:Number; /* HERO */ x = x / 30; // y = y / 30; // r = 8 / 30; // bodyDef = new b2BodyDef(); bodyDef.position.Set(x, y); circleDef = new b2CircleDef(); circleDef.radius = r; circleDef.density = 1; circleDef.friction = 1; circleDef.restitution = 0.2; hero = world.CreateBody(bodyDef); hero.SetUserData("hero"); // " " hero.CreateShape(circleDef); hero.SetMassFromShapes(); }
関数をmain()に再度追加します。
CreateHero(0, 0);
コンパイルすると、すでに何か新しいものが見えます。中央に白いボールが現れました。
しかし、あなたが気配りのある人であれば、彼は動きません。重力をオフにしたことを覚えておいてください。 なんで? 世界の擬似回転を作成します。 私たちの世界では重力なので、単に動的であることが義務付けられています。
したがって、「左」と「右」のキーで世界の回転を行います。
スプライト自体を世界とともに回転させ、重力を変更する必要があります。
私たちのヒーローの静的な「部屋」を回転させることができない理由を理解してほしい%)
2つのパブリック変数を追加します。
public var keyPressedRight:Boolean; public var keyPressedLeft:Boolean;
メインのリスナー():
parent.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener); parent.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
それに応じて、機能自体:
public function keyDownListener(event:KeyboardEvent):void { switch(event.keyCode) { case 37: keyPressedRight = true; break; case 39: keyPressedLeft = true; break; } } public function keyUpListener(event:KeyboardEvent):void { switch(event.keyCode) { case 37: keyPressedRight=false; break; case 39: keyPressedLeft = false; break; } }
次に、enterFrameListenerに移動して、次を追加します。
if (keyPressedRight) rotator -= 4; else if(keyPressedLeft) rotator += 4;
スプライトを回転させます:
sprite.rotation = rotator;
管理の準備ができました。 次に、コントロールを物理エンジンにバインドし、回転子に依存する重力を作成します。
var angle:Number = (270 + rotator_fix) / 180 * Math.PI; var pseudo_gravity:b2Vec2 = b2Vec2.Make(Math.cos(angle), -Math.sin(angle));
重力ベクトルを計算したので、今度はそれをヒーローに適用する必要があります。
for (var body:b2Body = world.GetBodyList(); body; body = body.GetNext()) // . { if (body.GetUserData() == "hero") // userdata - hero, . { pseudo_gravity.x *= 9.8 * body.GetMass(); pseudo_gravity.y *= 9.8 * body.GetMass(); body.ApplyForce(pseudo_gravity, body.GetWorldCenter()); // } }
コンパイルします! 途中でがらくたを追加します。 関数を作成します。
public function CreateStaticRect(x:Number, y:Number, w:Number, h:Number):void { var total_x:Number = ((x + w / 2) - 150) / 30; var total_y:Number = ((y + h / 2) - 150) / 30; var total_w:Number = w / 30; var total_h:Number = h / 30; var body:b2Body; var bodyDef:b2BodyDef; var polygon:b2PolygonDef; bodyDef = new b2BodyDef(); polygon = new b2PolygonDef(); bodyDef.position.Set(0, 0); bodyDef.position.Set(total_x, total_y); polygon.SetAsBox(total_w / 2, total_h / 2); polygon.density = 0.0; polygon.friction = 0.5; polygon.restitution = 0.2; body = world.CreateBody(bodyDef); body.CreateShape(polygon); body.SetMassFromShapes(); body.SetUserData("box"); }
そしてメイン()の終わりに:
CreateStaticRect(0, 150, 150, 10);
顔の準備ができた「プロトタイプ」。
まとめ
これがそのような段階的な手順です。 親愛なる友人、あなたがそれを好めば、私は間違いなく多くの記事を書くでしょう、最終的に私達はこのような何かを得ます。
PS:もう一度、すべてのリンクを提供します。
ソース | Swfファイル | SWFを埋め込む | Box2Dlib
PSS:あらゆる種類の無料ホスティングへのリンクでごめんなさい。 サーバーはありません。
UPD: パートII