|
Adobe Flash非公式テクニカルノート
StarlingフレームワークでつくったテクスチャのボールをBox2Dで弾ませる
ID: FN1203004 |
Product: Flash CS5 and above |
Platform: All |
Version: 11 and above/ActionScript 3.0 |
Starlingフレームワークで使える物理演算エンジン「Box2DFlash」(以下単に単にBox2Dと呼びます)の基本的な使い方は「Starlingフレームワークで物理演算エンジンBox2Dを使う」で解説しました。本稿では、そのスクリプトに手を加えて、テクスチャからつくったボールを弾ませてみます。
なお、Box2Dはバージョンによって、細かい仕様が変わることもありますのでご注意ください。本稿ではバージョン2.1aを使います。また、Starlingフレームワークの基礎とその使い方については、「Starlingフレームワークを使う」をお読みください。
01 テクスチャでボールをつくる
物理演算シミュレーションに入る前に、Starlingフレームワークでテクスチャのボールをつくりましょう。背景が抜かれたボール用の円形ビットマップをFlashの[ライブラリ]に納め、[ビットマッププロパティ]ダイアログボックスでクラスを設定しておきます(図001)。
図001■[ライブラリ]に用意したボール用ビットマップにクラスを設定する
さて、この[ライブラリ]のビットマップをどうやってStarlingフレームワークにもっていくかです。というのは、前出「Starlingフレームワークを使う」01「Starlingフレームワークで何からつくり始めるか」に述べたとおり、「Starlingフレームワークの表示リストには、Starlingの表示オブジェクトしか加えられません」。そこで使うのが、Textureクラスです。
テクスチャ(texture)というのは、Starlingフレームワークでイメージを表示するために用いられるビットマップデータのことです。TextureクラスにはTexture.fromBitmapData()という静的メソッドが備わっていて、BitmapDataオブジェクトからTextureインスタンスがつくれます。
もっとも、Textureインスタンスは表示オブジェクトではないので、そのままではStarlingフレームワークのステージには置けません。Imageクラスのコンストラクタメソッドに引数として渡したうえで、そのImageオブジェクトを表示リストに加えます。
var myTexture:Texture = Texture.fromBitmapData(BitmapDataオブジェクト);
var myImage:Image = new Image(myTexture);
addChild(myImage);
|
Starlingフレームワークの表示リスト最上位(ルート)に置く表示オブジェクトとして以下のクラス(MySprite)を定めると(スクリプト001)、[ライブラリ]にクラス(Pen)を設定したビットマップがステージの中央に表示されます(図002)。なお、FLAファイル(ASファイルと同階層)には、つぎのフレームアクションが書かれているものとします(前出「Starlingフレームワークを使う」03「Starlingフレームワークの初期化」スクリプト002参照)。
// フレームアクション: メインタイムライン
import starling.core.Starling;
var myStarling:Starling = new Starling(MySprite, stage);
myStarling.start();
|
スクリプト001■[ライブラリ]のビットマップからテクスチャのボールをつくって表示する
// ActionScript 3.0クラス定義ファイル: MySprite.as
- package {
- import flash.display.BitmapData;
- import starling.display.Sprite;
- import starling.display.Image;
- import starling.textures.Texture;
- import starling.events.Event;
- public class MySprite extends Sprite {
- public function MySprite() {
- addEventListener(Event.ADDED_TO_STAGE, initialize);
- }
- private function initialize(eventObject:Event):void {
- var nStageWidth:Number = stage.stageWidth;
- var nStageHeight:Number = stage.stageHeight;
- var myBitmapData:BitmapData = new Pen();
- var myTexture:Texture = Texture.fromBitmapData(myBitmapData);
- var nRadius:Number = myBitmapData.width / 2;
- var myBall:Image = createBall(nRadius, myTexture);
- myBall.x = nStageWidth / 2;
- myBall.y = nStageHeight / 2;
- addChild(myBall);
- }
- private function createBall(nRadius:Number, myTexture:Texture):Image {
- var myImage:Image = new Image(myTexture);
- myImage.pivotX = nRadius;
- myImage.pivotY = nRadius;
- return myImage;
- }
- }
- }
|
図002■[ライブラリ]のビットマップがStarlingフレームワークでステージ中央に表示された
初期設定のメソッド(initialize())は、[ライブラリ]のビットマップに設定したクラス(Pen)からインスタンスをつくり、Texture.fromBitmapData()メソッドの引数に渡してTextureインスタンス(myTexture)にしています(スクリプト001第14〜15行目)。
さらに、ボールの半径とTextureインスタンスを引数として、ボールのImageインスタンスをつくるメソッド(createBall())が呼出されます(スクリプト001第17行目)。このメソッドは、受取ったTextureオブジェクト(myTexture)から新たなImageインスタンス(myImage)をつくり、半径(nRadius)に合わせてインスタンスの原点を調整します(第23〜25行目)。そして、Imageインスタンスを返します(第26行目)。
02 Box2Dのスクリプトにテクスチャのボールを組込む
初めに述べましたとおり、本稿はスクリプトを頭から書くのではなく、FN1202006「Starlingフレームワークで物理演算エンジンBox2Dを使う」のサンプルに手を加えます。具体的には、スクリプト003「動的な剛体が落下して静的な剛体のうえで弾むアニメーション」です(FN1203004図005再掲)。
FN1203004図005■落下した矩形の剛体が床で弾む(再掲)
この落下する矩形のQuadインスタンスを、テクスチャのボールに置換えます。そのために、FN1203004スクリプト003のクラス(MySprite)にまずはつぎのような追加・修正を加えます。第1に、落下する矩形のQuadインスタンスを扱う処理は、スクリプトから除きます。プロパティ(boxEdge)やメソッド(createDynamicBox())とその呼出しのステートメントなどです。
第2に、テクスチャのボールをつくり、Box2Dの剛体として組入れます。Textureインスタンス(myTexture)のつくり方は、前掲スクリプト001(第14〜16行目)と同じです。Box2Dの剛体に組入れるメソッド(createDynamicBall())は後で定めますので、その呼出しを初期設定のメソッド(initialize())に加え、でき上がったボールのImageインスタンス(myBall)は表示リストに納めます。
// import宣言追加
import flash.display.BitmapData;
import starling.display.Image;
import starling.textures.Texture;
// ...[中略]...
public class MySprite extends Sprite {
// ...[中略]...
// private var boxEdge:Number = 20; // 削除
// ...[中略]...
private function initialize(eventObject:Event):void {
// ...[中略]...
// [ライブラリ]のビットマップからTextureインスタンスをつくる
var myBitmapData:BitmapData = new Pen();
var myTexture:Texture = Texture.fromBitmapData(myBitmapData);
var nRadius:Number = myBitmapData.width / 2;
// ...[中略]...
// テクスチャのボールを剛体として表示リストに加える
// var myQuad:Quad = createDynamicBox(nCenterX, boxEdge, boxEdge, boxEdge, 0x0000FF); // 削除
var myBall:Image = createDynamicBall(nCenterX, 0, nRadius, myTexture);
// addChild(myQuad); // 削除
addChild(myBall);
// ...[中略]...
}
// ...[中略]...
/* 削除
private function createDynamicBox(nX:Number, nY:Number, nWidth:Number, nHeight:Number, nColor:uint):Quad {
// ...[中略]...
}
*/
// ...[中略]...
}
|
それでは、取りあえずメソッドをふたつ定義します。できあがりのスクリプトは、後にスクリプト002として掲げます。引用したステートメントには、その行番号を添えました。
ひとつ目は、初期設定のメソッド(initialize())から呼出すメソッド(createDynamicBall())で、Box2Dの剛体を定義し、テクスチャからつくったImageインスタンスを返します(スクリプト002第52〜59行目)。中からふたつのメソッド(createBodyDef()とcreateBallForBodyDef())を呼出しています(前者は前出「Starlingフレームワークで物理演算エンジンBox2Dを使う」ですでに定められています)。この引用部分だけでは、まだ完成していません。
ふたつ目は、ひとつ目のメソッド(createDynamicBall())から呼出したメソッド(createBallForBodyDef())です。テクスチャからImageインスタンスをつくり、剛体定義のb2BodyDefオブジェクトに関連づけて返します(スクリプト002第73〜79行目)。中身は前掲スクリプト001のImageインスタンスをつくるメソッド(createBall())とほとんど同じで、ただインスタンスをb2BodyDef.userDataプロパティに設定するステートメントが加わっています(第77行目)。
// Box2Dの剛体を定義してボールのImageインスタンスを返す
- private function createDynamicBall(nX:Number, nY:Number, nRadius:Number, myTexture:Texture):Image {
- var bodyDef:b2BodyDef = createBodyDef(nX, nY, b2Body.b2_dynamicBody);
- var myImage:Image = createBallForBodyDef(bodyDef, nRadius, myTexture);
- return myImage;
- }
// テクスチャからつくったImageインスタンスに剛体定義を関連づけて返す
- private function createBallForBodyDef(bodyDef:b2BodyDef, nRadius:Number, myTexture:Texture):Image {
- var myImage:Image = new Image(myTexture);
- myImage.pivotX = nRadius;
- myImage.pivotY = nRadius;
- bodyDef.userData = myImage;
- return myImage;
- }
|
ここまで修正しただけで動きを確かめると、ステージ左上角にテクスチャからつくったボールのImageインスタンスが表れます(図003)。Box2Dのシミュレーションにはまだ組込んでいないので、インスタンスは動きません。けれど、物理演算はメモリ内で行われます。ですから、目に見えるところで確かめておくと、後で問題が起こったときにも原因を絞り込みやすくなります。
図003■ステージ左上角にボールのインスタンスが表れる
03 テクスチャのボールをBox2Dで弾ませる
それでは、テクスチャでつくったボールをBox2Dのシミュレーションに組入れます。前項で定めた、Box2Dの剛体を定義してボールのImageインスタンスを返すメソッド(createDynamicBall())には、まだ足りないところがあるといいました。このメソッドに、ステートメントを3行加えます(スクリプト002第55〜57行目)。
まず、フィクスチャの定義となるb2FixtureDefインスタンス(fixtureDef)をつくります(スクリプト002第55行目)。そのための関数(createFixtureDefAndCircleShape)を新たに定めます。つぎに、フィクスチャに、重さ(密度)や滑りやすさ(摩擦)、跳ね返りの度合い(弾性)などを定めます(第56行目)。そして、剛体とフィクスチャのふたつの定義から剛体(body)をつくるのです(第57行目)。後のふたつの処理については、すでにメソッド(setFixtureDef()とcreateBodyWithFixture())が定められていますので、それぞれに必要な引数を与えて呼出します。
b2FixtureDefインスタンスをつくるメソッド(createFixtureDefAndCircleShape())は、新たなb2FixtureDefインスタンス(fixtureDef)に剛体のかたちを定めた上で、インスタンスを返します(スクリプト002第85〜90行目)。ボールのかたちは円形ですので、b2CircleShapeオブジェクトでつくります。コンストラクタメソッドの引数は円の半径です(第87行目)。b2CircleShapeオブジェクトは、b2FixtureDefインスタンスのb2FixtureDef.shapeプロパティに設定します(第88行目)。
// import宣言追加
- import Box2D.Collision.Shapes.b2CircleShape;
- public class MySprite extends Sprite {
// Box2Dの剛体を定義してボールのImageインスタンスを返す
- private function createDynamicBall(nX:Number, nY:Number, nRadius:Number, myTexture:Texture):Image {
- var bodyDef:b2BodyDef = createBodyDef(nX, nY, b2Body.b2_dynamicBody);
- var myImage:Image = createBallForBodyDef(bodyDef, nRadius, myTexture);
// 3ステートメント追加
- var fixtureDef:b2FixtureDef = createFixtureDefAndCircleShape(nRadius);
- setFixtureDef(fixtureDef, density, friction, restitution);
- var body:b2Body = createBodyWithFixture(world, bodyDef, fixtureDef);
- return myImage;
- }
// 剛体のかたちが定められた新たなb2FixtureDefインスタンスを返す
- private function createFixtureDefAndCircleShape(nRadius:Number):b2FixtureDef {
- var fixtureDef:b2FixtureDef = new b2FixtureDef();
- var myShape:b2CircleShape = new b2CircleShape(nRadius * SCALE);
- fixtureDef.shape = myShape;
- return fixtureDef;
- }
- }
|
これでクラス(MySprite.as)の修正は済みました。テクスチャのボールが物理演算シミュレーションに組込まれましたので、ボールがステージ上から落ちてきて、下にある床に当たって弾みます(図004)。定義したクラス(MySprite)全体は、以下のスクリプト002のとおりです。
図004■テクスチャのボールが落ちて床で弾む
スクリプト002■テクスチャでつくったボールの剛体が床に落ちて弾むアニメーション
// ActionScript 3.0クラス定義ファイル: MySprite.as
- package {
- import flash.display.BitmapData;
- import starling.display.DisplayObject;
- import starling.display.Sprite;
- import starling.display.Quad;
- import starling.display.Image;
- import starling.textures.Texture;
- import starling.events.Event;
- import Box2D.Common.Math.b2Vec2;
- import Box2D.Dynamics.b2World;
- import Box2D.Dynamics.b2BodyDef;
- import Box2D.Dynamics.b2Body;
- import Box2D.Dynamics.b2FixtureDef;
- import Box2D.Collision.Shapes.b2PolygonShape;
- import Box2D.Collision.Shapes.b2CircleShape;
- public class MySprite extends Sprite {
- private const SCALE:Number = 1 / 30;
- private var world:b2World;
- private var gravityVertical:Number = 10;
- private var velocityIterations:int = 10;
- private var positionIterations:int = 10;
- private var time:Number = 1 / 24;
- private var density:Number = 1;
- private var friction:Number = 0.5;
- private var restitution:Number = 0.8;
- public function MySprite() {
- addEventListener(Event.ADDED_TO_STAGE, initialize);
- }
- private function initialize(eventObject:Event):void {
- var nStageWidth:Number = stage.stageWidth;
- var nStageHeight:Number = stage.stageHeight;
- var nCenterX:Number = nStageWidth / 2;
- var nFloorWidth:Number = nStageWidth * 0.8;
- var nFloorHeight:Number = 20;
- var myBitmapData:BitmapData = new Pen();
- var myTexture:Texture = Texture.fromBitmapData(myBitmapData);
- var nRadius:Number = myBitmapData.width / 2;
- world = new b2World(new b2Vec2(0, gravityVertical), true);
- var floorQuad:Quad = createStaticFloor(nCenterX,nStageHeight - nFloorHeight,nFloorWidth,nFloorHeight,0xCCCCCC);
- addChild(floorQuad);
- var myBall:Image = createDynamicBall(nCenterX, 0, nRadius, myTexture);
- addChild(myBall);
- addEventListener(Event.ENTER_FRAME, update);
- }
- private function createStaticFloor(nX:Number, nY:Number, nWidth:Number, nHeight:Number, nColor:uint):Quad {
- var bodyDef:b2BodyDef = createBodyDef(nX, nY);
- var myQuad:Quad = createQuadForBodyDef(bodyDef, nWidth, nHeight, nColor);
- var fixtureDef:b2FixtureDef = createFixtureDefWithShape(nWidth, nHeight);
- var body:b2Body = createBodyWithFixture(world, bodyDef, fixtureDef);
- return myQuad;
- }
- private function createDynamicBall(nX:Number, nY:Number, nRadius:Number, myTexture:Texture):Image {
- var bodyDef:b2BodyDef = createBodyDef(nX, nY, b2Body.b2_dynamicBody);
- var myImage:Image = createBallForBodyDef(bodyDef, nRadius, myTexture);
- var fixtureDef:b2FixtureDef = createFixtureDefAndCircleShape(nRadius);
- setFixtureDef(fixtureDef, density, friction, restitution);
- var body:b2Body = createBodyWithFixture(world, bodyDef, fixtureDef);
- return myImage;
- }
- private function createBodyDef(nX:Number, nY:Number, nType:uint= 0):b2BodyDef {
- var bodyDef:b2BodyDef = new b2BodyDef();
- bodyDef.position.Set((nX * SCALE), nY * SCALE);
- bodyDef.type = nType;
- return bodyDef;
- }
- private function createQuadForBodyDef(bodyDef:b2BodyDef, nWidth:Number, nHeight:Number, nColor:uint=0):Quad {
- var myQuad:Quad = new Quad(nWidth,nHeight,nColor);
- myQuad.pivotX = myQuad.width / 2;
- myQuad.pivotY = myQuad.height / 2;
- bodyDef.userData = myQuad;
- return myQuad;
- }
- private function createBallForBodyDef(bodyDef:b2BodyDef, nRadius:Number, myTexture:Texture):Image {
- var myImage:Image = new Image(myTexture);
- myImage.pivotX = nRadius;
- myImage.pivotY = nRadius;
- bodyDef.userData = myImage;
- return myImage;
- }
- private function createFixtureDefWithShape(nWidth:Number, nHeight:Number):b2FixtureDef {
- var fixtureDef:b2FixtureDef = new b2FixtureDef();
- setShapeToFixtureDef(fixtureDef, nWidth / 2, nHeight / 2);
- return fixtureDef;
- }
- private function createFixtureDefAndCircleShape(nRadius:Number):b2FixtureDef {
- var fixtureDef:b2FixtureDef = new b2FixtureDef();
- var myShape:b2CircleShape = new b2CircleShape(nRadius * SCALE);
- fixtureDef.shape = myShape;
- return fixtureDef;
- }
- private function setShapeToFixtureDef(fixtureDef:b2FixtureDef, nX:Number, nY:Number):void {
- var myShape:b2PolygonShape = new b2PolygonShape();
- myShape.SetAsBox(nX * SCALE, nY * SCALE);
- fixtureDef.shape = myShape;
- }
- private function setFixtureDef(fixtureDef:b2FixtureDef, density:Number, friction:Number, restitution:Number = 0):void {
- fixtureDef.density = density;
- fixtureDef.friction = friction;
- fixtureDef.restitution = restitution;
- }
- private function createBodyWithFixture(world:b2World, bodyDef:b2BodyDef, fixtureDef:b2FixtureDef):b2Body {
- var body:b2Body = world.CreateBody(bodyDef);
- body.CreateFixture(fixtureDef);
- return body;
- }
- private function update(eventObject:Event):void {
- world.Step(time, velocityIterations, positionIterations);
- var body:b2Body = world.GetBodyList();
- while (body) {
- var myObject:DisplayObject = body.GetUserData() as DisplayObject;
- if (myObject) {
- var position:b2Vec2 = body.GetPosition();
- myObject.x = position.x / SCALE;
- myObject.y = position.y / SCALE;
- myObject.rotation = body.GetAngle();
- }
- body = body.GetNext();
- }
- }
- }
- }
|
04 ボールをたくさん落として互いに弾ませる
ひとつのボールが無事に落ちましたので、数を増やしてみましょう。100個のボールをランダムな水平位置から、時間差で落とすことにします。Timerクラスを使えば、時間の間隔も、イベントリスナーの呼出し回数も決められるので便利です。でき上がりのクラス(MySprite)は、後にスクリプト003として掲げてあります。そのうち、修正した部分をつぎに抜出しました。
- import flash.utils.Timer;
- import flash.events.TimerEvent;
- public class MySprite extends Sprite {
- private var restitution:Number = 0.8; // 0.5;
// プロパティとして宣言
- private var myTexture:Texture;
- private var nStageWidth:Number;
- private var nStageHeight:Number;
- private var nRadius:Number;
- private var myTimer:Timer = new Timer(200, 100);
- private function initialize(eventObject:Event):void {
// var nStageWidth:Number = stage.stageWidth;
- nStageWidth = stage.stageWidth;
// var nStageHeight:Number = stage.stageHeight;
- nStageHeight = stage.stageHeight;
// var myTexture:Texture = Texture.fromBitmapData(myBitmapData);
- myTexture = Texture.fromBitmapData(myBitmapData);
// var nRadius:Number = myBitmapData.width / 2;
- nRadius = myBitmapData.width / 2;
// var myBall:Image = createDynamicBall(nCenterX, 0, nRadius, myTexture);
// addChild(myBall);
- myTimer.addEventListener(TimerEvent.TIMER, addBall);
- myTimer.start();
- }
// ランダムな水平位置からボールを落とす
- private function addBall(eventObject:TimerEvent):void {
- var nX:Number = Math.random() * nStageWidth;
- var myBall:Image = createDynamicBall(nX, -nRadius, nRadius, myTexture);
- addChild(myBall);
- }
- }
|
まず、Timerクラスを使った処理を見ていきます。必要なクラスをimport宣言し(スクリプト003第2〜3行目)、Timerインスタンスをプロパティ(myTimer)に納めます(第32行目)。200ミリ秒間隔で、イベントリスナーを100回呼出します。そして、初期設定のメソッド(initialize())は、Timerオブジェクトにリスナーメソッド(addBall())を定めて、Timer.start()メソッドを呼出します(第49〜50行目)。
つぎに、リスナーメソッド(addBall())は、呼出されるたびにひとつボールの剛体を定義してImageインスタンスをつくります(スクリプト003第52〜56行目)。前掲スクリプト002(第41〜42行目)では、初期設定のメソッド(initialize())でこの処理を行っていましたので、そのステートメントは削除しました。また、このリスナーメソッドの中で用いている値には、初期設定のメソッド(initialize())で得ているもの(nStageWidthやnRadius、myTexture)があります。したがって、それらはプロパティとして宣言しました(第28〜31行目)。
これで、200ミリ秒ごとにランダムな水平位置から、つぎつぎと100個のボールが落とされ、互いにぶつかり合います(図005)。
図005■ランダムな水平位置から時間差で100個のボールが落とされて互いにぶつかり合う
スクリプト003■ボールの剛体をつぎつぎに落として互いに弾ませるアニメーション
// ActionScript 3.0クラス定義ファイル: MySprite.as
- package {
- import flash.display.BitmapData;
- import flash.utils.Timer;
- import flash.events.TimerEvent;
- import starling.display.DisplayObject;
- import starling.display.Sprite;
- import starling.display.Quad;
- import starling.display.Image;
- import starling.textures.Texture;
- import starling.events.Event;
- import Box2D.Common.Math.b2Vec2;
- import Box2D.Dynamics.b2World;
- import Box2D.Dynamics.b2BodyDef;
- import Box2D.Dynamics.b2Body;
- import Box2D.Dynamics.b2FixtureDef;
- import Box2D.Collision.Shapes.b2PolygonShape;
- import Box2D.Collision.Shapes.b2CircleShape;
- public class MySprite extends Sprite {
- private const SCALE:Number = 1 / 30;
- private var world:b2World;
- private var gravityVertical:Number = 10;
- private var velocityIterations:int = 10;
- private var positionIterations:int = 10;
- private var time:Number = 1 / 24;
- private var density:Number = 1;
- private var friction:Number = 0.5;
- private var restitution:Number = 0.8;
- private var myTexture:Texture;
- private var nStageWidth:Number;
- private var nStageHeight:Number;
- private var nRadius:Number;
- private var myTimer:Timer = new Timer(200, 100);
- public function MySprite() {
- addEventListener(Event.ADDED_TO_STAGE, initialize);
- }
- private function initialize(eventObject:Event):void {
- nStageWidth = stage.stageWidth;
- nStageHeight = stage.stageHeight;
- var nCenterX:Number = nStageWidth / 2;
- var nFloorWidth:Number = nStageWidth * 0.8;
- var nFloorHeight:Number = 20;
- var myBitmapData:BitmapData = new Pen();
- myTexture = Texture.fromBitmapData(myBitmapData);
- nRadius = myBitmapData.width / 2;
- world = new b2World(new b2Vec2(0, gravityVertical), true);
- var floorQuad:Quad = createStaticFloor(nCenterX, nStageHeight - nFloorHeight, nFloorWidth, nFloorHeight, 0xCCCCCC);
- addChild(floorQuad);
- addEventListener(Event.ENTER_FRAME, update);
- myTimer.addEventListener(TimerEvent.TIMER, addBall);
- myTimer.start();
- }
- private function addBall(eventObject:TimerEvent):void {
- var nX:Number = Math.random() * nStageWidth;
- var myBall:Image = createDynamicBall(nX, -nRadius, nRadius, myTexture);
- addChild(myBall);
- }
- private function createStaticFloor(nX:Number, nY:Number, nWidth:Number, nHeight:Number, nColor:uint):Quad {
- var bodyDef:b2BodyDef = createBodyDef(nX,nY);
- var myQuad:Quad = createQuadForBodyDef(bodyDef, nWidth, nHeight, nColor);
- var fixtureDef:b2FixtureDef = createFixtureDefWithShape(nWidth, nHeight);
- var body:b2Body = createBodyWithFixture(world, bodyDef, fixtureDef);
- return myQuad;
- }
- private function createDynamicBall(nX:Number, nY:Number, nRadius:Number, myTexture:Texture):Image {
- var bodyDef:b2BodyDef = createBodyDef(nX, nY, b2Body.b2_dynamicBody);
- var myImage:Image = createBallForBodyDef(bodyDef, nRadius, myTexture);
- var fixtureDef:b2FixtureDef = createFixtureDefAndCircleShape(nRadius);
- setFixtureDef(fixtureDef, density, friction, restitution);
- var body:b2Body = createBodyWithFixture(world, bodyDef, fixtureDef);
- return myImage;
- }
- private function createBodyDef(nX:Number, nY:Number, nType:uint= 0):b2BodyDef {
- var bodyDef:b2BodyDef = new b2BodyDef();
- bodyDef.position.Set((nX * SCALE), nY * SCALE);
- bodyDef.type = nType;
- return bodyDef;
- }
- private function createQuadForBodyDef(bodyDef:b2BodyDef, nWidth:Number, nHeight:Number, nColor:uint=0):Quad {
- var myQuad:Quad = new Quad(nWidth, nHeight, nColor);
- myQuad.pivotX = myQuad.width / 2;
- myQuad.pivotY = myQuad.height / 2;
- bodyDef.userData = myQuad;
- return myQuad;
- }
- private function createBallForBodyDef(bodyDef:b2BodyDef, nRadius:Number, myTexture:Texture):Image {
- var myImage:Image = new Image(myTexture);
- myImage.pivotX = nRadius;
- myImage.pivotY = nRadius;
- bodyDef.userData = myImage;
- return myImage;
- }
- private function createFixtureDefWithShape(nWidth:Number, nHeight:Number):b2FixtureDef {
- var fixtureDef:b2FixtureDef = new b2FixtureDef();
- setShapeToFixtureDef(fixtureDef, nWidth / 2, nHeight / 2);
- return fixtureDef;
- }
- private function setShapeToFixtureDef(fixtureDef:b2FixtureDef, nX:Number, nY:Number):void {
- var myShape:b2PolygonShape = new b2PolygonShape();
- myShape.SetAsBox(nX * SCALE, nY * SCALE);
- fixtureDef.shape = myShape;
- }
- private function setFixtureDef(fixtureDef:b2FixtureDef, density:Number, friction:Number, restitution:Number = 0):void {
- fixtureDef.density = density;
- fixtureDef.friction = friction;
- fixtureDef.restitution = restitution;
- }
- private function createBodyWithFixture(world:b2World, bodyDef:b2BodyDef, fixtureDef:b2FixtureDef):b2Body {
- var body:b2Body = world.CreateBody(bodyDef);
- body.CreateFixture(fixtureDef);
- return body;
- }
- private function createFixtureDefAndCircleShape(nRadius:Number):b2FixtureDef {
- var fixtureDef:b2FixtureDef = new b2FixtureDef();
- var myShape:b2CircleShape = new b2CircleShape(nRadius * SCALE);
- fixtureDef.shape = myShape;
- return fixtureDef;
- }
- private function update(eventObject:Event):void {
- world.Step(time, velocityIterations, positionIterations);
- var body:b2Body = world.GetBodyList();
- while (body) {
- var myObject:DisplayObject = body.GetUserData() as DisplayObject;
- if (myObject) {
- var position:b2Vec2 = body.GetPosition();
- myObject.x = position.x / SCALE;
- myObject.y = position.y / SCALE;
- myObject.rotation = body.GetAngle();
- }
- body = body.GetNext();
- }
- }
- }
- }
|
作成者: 野中文雄
作成日: 2012年2月19日
Copyright ©
2001-2012 Fumio Nonaka. All rights reserved.
|