■物理エンジン for Flash → http://box2dflash.sourceforge.net/
Box2DFlashで作られた引越し奉行というゲームみてから気になってた。
ちょくちょくいろんなところで、ゲームに使われている。
おもしろそうなので手を出してみた。
とりあえず参考にしたサンプルを、ちょっと改造して動かす。
最初に画面をクリックしてください。
床と円を2つ設置。「←」「↑」「→」キーで円に力が加わります。
■物理エンジンをセットアップし,箱を落とすFlashを作る
ここのサンプルコードを元に改造しました。
■Master of None
オワタの冒険のサンプルコードを参考にさせていただきました。
ドキュメント少ないですね・・・みなさん何みて作ってんだろ・・・
とりあえず。わかったのは、
worldとbox定義の仕方と、m_linearVelocityで力を加えられることくらいか。。
ACTIONSCRIPT:
- package src {
- import Box2D.Collision.b2AABB;
- import Box2D.Collision.Shapes.b2CircleDef;
- import Box2D.Collision.Shapes.b2PolygonDef;
- import Box2D.Common.Math.b2Vec2;
- import Box2D.Dynamics.b2Body;
- import Box2D.Dynamics.b2BodyDef;
- import Box2D.Dynamics.b2DebugDraw;
- import Box2D.Dynamics.b2World;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.KeyboardEvent;
- import flash.events.MouseEvent;
- import flash.events.TextEvent;
- import flash.text.TextField;
- import flash.ui.Keyboard;
- /**
- * @author okm
- */
- public class LabyrinsSuite extends Sprite{
- private var world:b2World;
- private var circle:b2Body;
- private var testSp:Sprite;
- private var m_sprite:Sprite;
- public function LabyrinsSuite() {
- var textField:TextField = new TextField;
- textField.text = "click me ";
- textField.x = 100;
- textField.y = 100;
- textField.selectable = false;
- this.addChild(textField);
- stage.addEventListener(MouseEvent.CLICK, go);
- stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
- }
- public function go(event:MouseEvent):void {
- ////////////////////////////////////////
- // 物理エンジンのセットアップ
- // 外枠を定義する
- var worldAABB:b2AABB = new b2AABB();
- worldAABB.lowerBound.Set(-100, -100);
- worldAABB.upperBound.Set(100, 100);
- // 重力を下方向に10m/s^2とする
- var gravity:b2Vec2 = new b2Vec2(0, 10);
- // 外枠と重力を指定して、物理エンジン全体をセットアップする
- world = new b2World(worldAABB, gravity, true);
- ////////////////////////////////////////
- // 床の設置
- // 床は画面の下のほうに設置します
- // 床の位置を左から2.5m、上から3mとする
- var floorBodyDef:b2BodyDef = new b2BodyDef();
- floorBodyDef.position.Set(2.5, 3);
- // 床の形を、幅4m、厚さ20cmとする
- // 指定するのはその半分の値
- var floorShapeDef:b2PolygonDef = new b2PolygonDef();
- floorShapeDef.SetAsBox(2, 0.1);
- // 床を動かない物体として作る
- var floor:b2Body = world.CreateBody(floorBodyDef);
- floor.CreateShape(floorShapeDef);
- // 床その2
- var floorBodyDef2:b2BodyDef = new b2BodyDef();
- floorBodyDef2.position.Set(1.5, 2);
- var floorShapeDef2:b2PolygonDef = new b2PolygonDef();
- floorBodyDef2.angle = 0.2;
- floorShapeDef2.SetAsBox(1, 0.05);
- var floor2:b2Body = world.CreateBody(floorBodyDef2);
- floor2.CreateShape(floorShapeDef2);
- // 壁
- var floorBodyDef3:b2BodyDef = new b2BodyDef();
- floorBodyDef3.angle = 0.45;
- floorBodyDef3.position.Set(4, 2);
- var floorShapeDef3:b2PolygonDef = new b2PolygonDef();
- floorShapeDef3.SetAsBox(4, 2);
- var floor3:b2Body = world.CreateBody(floorBodyDef3);
- floor3.CreateShape(floorShapeDef2);
- /// 円
- var m_physScale:Number = 30;
- var circleDef:b2CircleDef = new b2CircleDef;
- circleDef.radius = 10/m_physScale;
- circleDef.density = 10.0/m_physScale;
- circleDef.friction = 1.0/m_physScale;
- circleDef.restitution = 0.2/m_physScale;
- var circleBD:b2BodyDef = new b2BodyDef();
- circleBD.position.Set(1,1);
- circle = world.CreateBody(circleBD);
- circle.CreateShape(circleDef);
- // 力を加える
- circle.m_linearVelocity.y = -5;
- circle.m_linearVelocity.x = -0.1;
- circle.SetMassFromShapes();
- /// 円2
- var circleDef2:b2CircleDef = new b2CircleDef;
- circleDef2.radius = 10/m_physScale;
- circleDef2.density = 10.0/m_physScale;
- circleDef2.friction = 1.0/m_physScale;
- circleDef2.restitution = 0.2/m_physScale;
- var circleBD2:b2BodyDef = new b2BodyDef();
- circleBD2.position.Set(1,3);
- var circle2:b2Body = world.CreateBody(circleBD2);
- circle2.CreateShape(circleDef2);
- circle2.SetMassFromShapes();
- ////////////////////////////////////////
- // 描画設定
- var debugDraw:b2DebugDraw = new b2DebugDraw();
- debugDraw.m_sprite = this;
- debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
- debugDraw.m_fillAlpha = 0.3; // 不透明度
- debugDraw.m_lineThickness = 1; // 線の太さ
- debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
- world.SetDebugDraw(debugDraw);
- this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
- }
- private var m_InputL:Number = 0;
- private var m_InputR:Number = 0;
- private var m_InputU:Number = 0;
- private var m_Dir:Number = 0;
- // キーが押されたときの処理
- private function keyDownHandler(event:KeyboardEvent):void {
- circle.WakeUp();
- if(event.keyCode == Keyboard.LEFT){
- m_InputL = 1;
- m_Dir = -1.0;
- }
- if(event.keyCode == Keyboard.RIGHT){
- m_InputR = 1;
- m_Dir = 1.0;
- }
- if(event.keyCode == Keyboard.UP){
- m_InputU = 1;
- }
- }
- private function keyUpHandler(event:KeyboardEvent):void {
- m_InputL = 0;
- m_InputR = 0;
- m_InputU = 0;
- }
- private function enterFrameHandler(event:Event):void {
- for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next) {
- if (bb.m_userData is Sprite) {
- bb.m_userData.x = bb.GetPosition().x * 30;//;
- bb.m_userData.y = bb.GetPosition().y * 30;// * m_physScale;
- bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
- }
- }
- if (m_InputU == 1) {
- circle.m_linearVelocity.y = -2;
- }
- if (m_InputL == 1) {
- circle.m_linearVelocity.x = -2;
- }
- if (m_InputR == 1) {
- circle.m_linearVelocity.x = +2;
- }
- if (world == null) {
- return;
- }
- // Flashはデフォルトで秒間24フレームなので、
- // 物理シミュレーションを1/24秒進める
- world.Step(1 / 24, 10);
- }
- }
- }
- Newer: Box2Dで 四角の一人ボール遊び
- Older: ModalBox.js にタイムアウト処理などを加える
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://parpue.net/web/31/trackback
- Listed below are links to weblogs that reference
- 物理エンジン Box2DFlashAS3 を使ってみる from parpue.net


