In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Box2DFlashAS3を使って作る物理演算ゲーム サンプルコード

Get Adobe Flash player
by ll_koba_ll 18 Nov 2009
/**
 * Copyright ll_koba_ll ( http://wonderfl.net/user/ll_koba_ll )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fjRb
 */

package {
    import flash.display.*;
    import flash.events.*;
    import flash.ui.Keyboard;

    import Box2D.Dynamics.*;
    import Box2D.Collision.*;
    import Box2D.Collision.Shapes.*;
    import Box2D.Dynamics.Joints.*;
    import Box2D.Dynamics.Contacts.*;
    import Box2D.Common.*;
    import Box2D.Common.Math.*;
    
    import com.flashdynamix.utils.SWFProfiler;

    [SWF(frameRate=30, width=500, height=500, backgroundColor="#000000")]
    public class Box2DSample01 extends Sprite {
        private var _world:b2World;
        private const DRAW_SCALE:Number = 100;
        private var _iterations:int = 10;
        private var _timeStep:Number = 1.0/30.0;
        private var _debug:Boolean = false;
        private var _gravity:b2Vec2;
        private var _doSleep:Boolean = true;

        private var _shipBody:b2Body;
        private var _goalBody:b2Body;
        private var _startBody:b2Body;
        private var _shipView:ShipView;
        private var _shipModel:ShipModel;

        public function Box2DSample01() {
            addEventListener(Event.ENTER_FRAME, function():void {
                if (stage != null) {
                    removeEventListener(Event.ENTER_FRAME, arguments.callee); 
                    init();
                }
            });
            _shipModel = new ShipModel();
            SWFProfiler.init(this);
        }

        private function init(e:Event = null):void {
            addEventListener(Event.ENTER_FRAME, update)

            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
            
            var worldAABB:b2AABB = new b2AABB();
            // 物理エンジンの範囲を決定
            worldAABB.lowerBound.Set(-100, -100);
            worldAABB.upperBound.Set(100, 100);
            // 重力の設定
            _gravity = new b2Vec2(0, 1);
            // ワールドの生成
            _world = new b2World(worldAABB, _gravity, _doSleep);
            
            // デバッグ表示
            if (_debug) {
                var dbgDraw:b2DebugDraw = new b2DebugDraw();
                var dbgSprite:Sprite = new Sprite();
                addChild(dbgSprite);
                dbgDraw.m_sprite = dbgSprite;
                dbgDraw.m_drawScale = DRAW_SCALE;
                dbgDraw.m_fillAlpha = 0.0;
                dbgDraw.m_alpha = 1.0;
                dbgDraw.m_lineThickness = 1.0;
                dbgDraw.m_drawFlags = 0xFFFFFFFF;
                _world.SetDebugDraw(dbgDraw);
            }

            // 各オブジェクトの生成
            var stw:Number = stage.stageWidth;
            var sth:Number = stage.stageHeight;
            createBox("floor", stw/2, sth, stw, 10);
            createBox("ceiling", stw/2, 0, stw, 10);
            createBox("leftWall", 0, sth/2, 10, sth);
            createBox("rightWall", stw, sth/2, 10, sth);
            createBox("start", 40, sth - 10, 60, 10);
            createBox("goal", stw - 40, sth - 10, 60, 10);
            createBox("centerWall", stw/2, sth/2 + 90/2, 20, sth - 90);

            initShip();

            // 衝突判定用のリスナー設定
            var cl:ContactListener = new ContactListener(this);
            _world.SetContactListener(cl);
        }


        public function gameClear():void {
            trace("gameClear");
        }

        public function gameOver():void {
            trace("gameOver");
        }

         
        private function initShip():void {
            // body生成
            var bodyDef:b2BodyDef;
            bodyDef = new b2BodyDef();
            bodyDef.position.x = 40/DRAW_SCALE;
            bodyDef.position.y = (stage.stageHeight - 40)/DRAW_SCALE;
            bodyDef.userData = {};
            bodyDef.userData.id = "ship";
            // 表示オブジェクト設定
            _shipView = new ShipView();
            bodyDef.userData.displayObject = _shipView; 
            addChild(bodyDef.userData.displayObject);

            // shape生成
            var boxDef:b2PolygonDef;
            boxDef = new b2PolygonDef();
            boxDef.SetAsBox(40/2/DRAW_SCALE,
                            40/2/DRAW_SCALE);
            boxDef.density = 0.1; // 密度
            boxDef.friction = 0.5; // 摩擦係数
            boxDef.restitution = 0.2; // 反発係数

            // ワールドに追加
            var body:b2Body;
            body = _world.CreateBody(bodyDef);
            body.CreateShape(boxDef);
            body.SetMassFromShapes();

            _shipBody = body;

        }

       
        private function createBox(id:String, x:Number, y:Number, w:Number, h:Number):void {
            // body生成
            var bodyDef:b2BodyDef = new b2BodyDef();
            bodyDef.position.x = x/DRAW_SCALE;
            bodyDef.position.y = y/DRAW_SCALE;
            bodyDef.userData = {};
            bodyDef.userData.id = id;

            // 表示オブジェクト作成
            var display:Sprite = new Sprite();
            var g:Graphics = display.graphics;
            g.lineStyle(1, 0xFFFFFF);
            g.drawRect(-w/2,-h/2,w,h);
            addChild(display);
            bodyDef.userData.displayObject = display;
            
            // Shape生成
            var boxDef:b2PolygonDef = new b2PolygonDef();
            boxDef.SetAsBox(w/2/DRAW_SCALE, h/2/DRAW_SCALE);
            boxDef.density = 0; // 固定されたオブジェクトに

            // ワールドに追加
            var body:b2Body = _world.CreateBody(bodyDef);
            body.CreateShape(boxDef);
        }
      
        private function update(event:Event):void {
            if (_world == null) return;

            _world.Step(_timeStep, 10);      

            for (var bb:b2Body = _world.m_bodyList; bb; bb = bb.m_next) {
                updateBodys(bb);
                // m_userDataに表示オブジェクトが入っている場合は、表示オブジェクトに計算結果を反映
                if (bb.m_userData) {
                    if (bb.m_userData.displayObject is Sprite) {
                        bb.m_userData.displayObject.x = bb.GetPosition().x * DRAW_SCALE;
                        bb.m_userData.displayObject.y = bb.GetPosition().y * DRAW_SCALE;
                        bb.m_userData.displayObject.rotation = bb.GetAngle() * (180/Math.PI);
                        if(bb.m_userData.displayObject.y > stage.stageHeight ) {
                            removeChild(bb.m_userData.displayObject);
                            _world.DestroyBody(bb);
                        }
                    } 
                }
            }            

            // 宇宙船を更新
            var a:Number = ((_shipBody.GetAngle() * 180/Math.PI) - 90) * Math.PI/180;
            var vx:Number = Math.cos(a) * _shipModel.power;
            var vy:Number = Math.sin(a) * _shipModel.power;
            
            var v:b2Vec2 = _shipBody.GetLinearVelocity();
            if (_shipModel.power > 0) {
                _shipBody.SetLinearVelocity(new b2Vec2(v.x + vx, v.y + vy));
            }
            _shipBody.SetAngularVelocity(_shipModel.vr * Math.PI/180);
    
        } 
        private function updateBodys(body:b2Body):void {
        }


        private function keyDownHandler(e:KeyboardEvent):void {
            // shipBodyがsleepしてる可能性があるので
            _shipBody.WakeUp();
            switch(e.keyCode) {
                case Keyboard.UP:
                    _shipView.showFire();
                    _shipModel.power = 0.1;                
                    break;

                case Keyboard.LEFT:
                    _shipModel.vr = -50;
                    break;
                
                case Keyboard.RIGHT:
                    _shipModel.vr = 50;
                    break;
            }
        }

        private function keyUpHandler(e:KeyboardEvent):void {
            switch(e.keyCode) {
                case Keyboard.UP:
                    _shipView.hideFire();
                    _shipModel.power = 0;                
                    break;

                case Keyboard.LEFT:
                case Keyboard.RIGHT:
                    _shipModel.vr = 0;
                    break;
            }
        }
    }
}



import flash.display.*;

class ShipModel {
    public var power:Number = 0;
    public var vr:Number = 0;
}

class ShipView extends Sprite {
    private var _fire:Sprite;

    public function ShipView() {
        var g:Graphics = graphics;
        g.lineStyle(1, 0xFFFFFF);
        g.drawRect(-20,-20, 40, 40);

        _fire = new Sprite();
        g = _fire.graphics;
        g.lineStyle(1, 0xFF0000);
        g.moveTo(-10, 0);
        g.lineTo(0, 20);
        g.lineTo(10, 0);
        g.lineTo(-10, 0);
        _fire.y = 23;
        _fire.visible = false;

        addChild(_fire);
    }

    public function showFire():void {
        _fire.visible = true;
    }
    
    public function hideFire():void {
        _fire.visible = false;
    }

}

import Box2D.Collision.Shapes.*;
import Box2D.Collision.b2ContactPoint;
import Box2D.Dynamics.b2ContactListener;
import Box2D.Dynamics.*;

class ContactListener extends b2ContactListener {
    private var _gameStage:Box2DSample01;

    public function ContactListener(gameStage:Box2DSample01) {
        _gameStage = gameStage;
    }

    public override function Add(point:b2ContactPoint):void
    {
        var s1:b2Shape = point.shape1;
        var s2:b2Shape = point.shape2;

        var b1:b2Body = s1.m_body;
        var b2:b2Body = s2.m_body;

        if (b1.m_userData == null && b2.m_userData == null) return;

        // b1が宇宙船の場合
        if (b1.m_userData != null && b1.m_userData.id == "ship") {
            if (b2.m_userData.id != "start" && 
                    b2.m_userData.id != "goal") {
                _gameStage.gameOver();
            } else if (b2.m_userData.id == "goal") {
                _gameStage.gameClear();
            }
        }
            
        // b2が宇宙船の場合
        if (b2.m_userData != null && b2.m_userData.id == "ship") {
            if (b1.m_userData.id != "start" && 
                    b1.m_userData.id != "goal") {
                _gameStage.gameOver();
            } else if (b1.m_userData.id == "goal") {
                _gameStage.gameClear();
            }
        }
    }

}