物理学を使用したFlashプラットフォームでの別のカジュアルの作成。 パートI

こんにちは親愛なる友人。



そもそも、私は比較的最近gamedevを扱ってきました。

したがって、コードと情報の品質に依存しないでください%)



この記事では、プロトタイプを例として使用して、Box2D物理エンジンをゲームに使用する方法について説明します。



幸運で記事が気に入ったら、第2部と第3部の両方があります。 最後に、 このようなゲームを取得します。 (はい、ゲームはひどく未完成で、記事と同じですが、グラフィックとセンサーのみがあります)

残りはカットの下にあります。







キャンプに行く





何が必要ですか?

  1. Box2D物理エンジン自体。 より安定しているため、バージョンが2.0.2であることが重要です。 はい、そしてそれらは同じパフォーマンスを持っています。

    ここまたはここからダウンロードできます(ただし、2番目のリンクにはこのソースコードもすべて含まれています)。
  2. as3で何かを作成した経験が必要です。
  3. 実際に私たちが書くもの、言い換えれば、IDE。 ちなみに、FlashDevelop(私のように)は無料で使用できます。 または、例えばAdobe Flash CS5を使用します。
  4. それぞれbrain.dllおよびhands.dll




背景





そのため、Box2Dは無料のオープンソースの2次元物理エンジン(ゲームだけでなく、ゲームでの物理世界のモデリング用)であり、C ++のためにErin Cattoによって開発されました。



しかし、Flashを使用してFlashに移植した別の良い人がいました。



誰かが、彼が非常に「太っている」と言います。例えば、ゆっくりと働く、誰か-逆に。 私は1つのことを知っています-彼らはそれで実際のゲームを作ります、したがって、おそらく、それは手に依存しています。



しかし、最初に、Box2Dに関する一般的な規定について説明する必要があります。 これらの規定は、要約の形式で提供されます。



  1. 測定単位としてBox2D ピクセルを使用しません
  2. 測定単位としてBox2D 国際システムC(si)-メートル、キログラム、秒(ISS)を使用します
  3. Box2Dは、10センチメートルから10メートルの範囲の動的オブジェクトで動作するように構成されました。つまり、ガラスからバスまでのオブジェクトを作成できます。
  4. Box2Dが動作する単位は画面の単位(ピクセル)と一致しないため、メートル(単位)の変換係数をピクセルに設定する必要があります。 たとえば、10センチ= 30ピクセルと指定できます。
  5. Box2Dは、動的および静的の2種類のオブジェクトで動作します
  6. 動的オブジェクトは、それら自体(レンガ、ボール、分子、ヘリコプター、車、人など)間の衝突の分析に関与します。静的-いいえ(地球、基礎、フレーム-絶対に破壊できないもの)
  7. Box2Dは、次の図との衝突を実装します:円、正方形、凸多角形。
  8. 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



All Articles