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

forked from: Box2Dの練習001 マウスでつかむ(FULL SCREENボタンに対応)

FULL SCREENボタンに対応してみた
床オブジェクトが画面サイズに合わせて伸縮・位置変わります
リサイズハンドラで処理をしています。
「CreateShape」で床オブジェクトのサイズを変更していますが、これで良いかは疑問・・・
Createだと新たにオブジェクトを作っている・・・わけではないのでしょうか??

@author fumix
/**
 * Copyright weBBBBB ( http://wonderfl.net/user/weBBBBB )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3kYY
 */

// forked from fumix's Box2Dの練習001 マウスでつかむ(FULL SCREENボタンに対応)
/**
* FULL SCREENボタンに対応してみた
* 床オブジェクトが画面サイズに合わせて伸縮・位置変わります
* リサイズハンドラで処理をしています。
* 「CreateShape」で床オブジェクトのサイズを変更していますが、これで良いかは疑問・・・
* Createだと新たにオブジェクトを作っている・・・わけではないのでしょうか??
**/
package {
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import Box2D.Collision.Shapes.b2CircleDef;
    import Box2D.Collision.Shapes.b2Shape;
    import Box2D.Dynamics.Joints.b2MouseJoint;
    import Box2D.Dynamics.Joints.b2MouseJointDef;

    import flash.events.MouseEvent;

    import Box2D.Dynamics.b2DebugDraw;
    import Box2D.Collision.Shapes.b2PolygonDef;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2World;
    import Box2D.Collision.b2AABB;

    import flash.events.Event;
    import flash.display.MovieClip;

    /**
     * @author fumix
     */
        [SWF(width=465, height=465, backgroundColor=000000)]
    public class main extends MovieClip {

        private var _iterations : int;
        private var _timeStep : Number;
        private var _physScale : Number;

        private var _world : b2World;

        //マウスジョイント
        var _mouseJoint : b2MouseJoint;
        

        /**
         * コンストラクタ
         */
        public function main() : void {
            if (stage) onInit();
             else addEventListener(Event.ADDED_TO_STAGE, onInit);
        }

        /**
         * 初期処理
         */
        private function onInit(event : Event = null) : void {
            removeEventListener(Event.ADDED_TO_STAGE, onInit);
            
            //ステージ設定
            stage.align = "TL";
            stage.scaleMode = "noScale";
            
            _iterations = 10;        //制度
            _timeStep = 1.0 / 24.0;    //実行速度
            _physScale = 30;        //表示倍率
            
            //ワールドの定義
            var worldAABB : b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-100.0, -100.0);
            worldAABB.upperBound.Set(100.0, 100.0);
            //重力の定義
            var gravity : b2Vec2 = new b2Vec2(0.0, 10.0);
            //スリープのONOFF
            var doSleep : Boolean = true;
            //ワールドのインスタンス作成
            _world = new b2World(worldAABB, gravity, doSleep);
            //----------------------------------
            // 床を作る
            //----------------------------------
            // 物体の定義を作る
            var wallBdDef : b2BodyDef = new b2BodyDef();
            var w : int = stage.stageWidth;
            var h : int = stage.stageHeight;
            wallBdDef.position.Set(w / 2 / _physScale, (h - 20) / _physScale);
            wallBdDef.angle = 0; //Math.PI / 24;

            // 形の定義を作る
            var wallShapeDef : b2PolygonDef = new b2PolygonDef();
            wallShapeDef.SetAsBox(w / _physScale, 10 / _physScale);
            wallShapeDef.friction = 2;        //摩擦力
            wallShapeDef.density = 0;        //密度
            wallShapeDef.restitution = 0.4;    //反発力

            // 物体を作る
            var wallBd:b2Body = _world.CreateBody(wallBdDef);
            wallBd.m_userData = new Object();
            wallBd.m_userData.id = 'wall';

            // 形を物体に追加する
            wallBd.CreateShape(wallShapeDef);
            
            //----------------------------------
            // 物体を10表示
            //----------------------------------
            for(var i : int = 0;i < 10;i++) {
                var dx : Number = (stage.stageWidth / 10 * i);
                createObject(dx);
            }

            //----------------------------------
            // DebugDraw を有効にする
            //----------------------------------
            var debugDraw : b2DebugDraw = new b2DebugDraw();
            debugDraw.m_sprite = this;
            debugDraw.m_drawScale = _physScale;
            debugDraw.m_fillAlpha = 1;
            debugDraw.m_lineThickness = 1;
            debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
            _world.SetDebugDraw(debugDraw);
            
            //毎フレームの処理
            stage.addEventListener(Event.ENTER_FRAME, EnterFrame);
            //タイマーイベント(1秒毎に物体を降らせる)
            var timerObj:Timer = new Timer(100);
            timerObj.addEventListener(TimerEvent.TIMER, onTimerHandler);
            timerObj.start();
            //イベントハンドラ
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);            
            //リサイズ処理
            stage.addEventListener(Event.RESIZE, resizeHandler);    

        }
        
        //リサイズ処理
        private function resizeHandler(event : Event) : void {
            //床の大きさ・位置を変更
            for (var b2body : b2Body = _world.m_bodyList;b2body; b2body = b2body.m_next) {
                if (b2body.m_userData) {
                    if (b2body.m_userData.id == "wall") {
                        var wallShapeDef : b2PolygonDef = new b2PolygonDef();
                        wallShapeDef.SetAsBox(stage.stageWidth / _physScale, 10 / _physScale);
                        b2body.CreateShape(wallShapeDef);
                        b2body.SetXForm(new b2Vec2(b2body.GetPosition().x, stage.stageHeight / _physScale), 0);
                    }
                }
            }
        }
        private function onTimerHandler(event : TimerEvent) : void {
                var dx : Number = stage.stageWidth*Math.random();
                createObject(dx);
        }
        private function mouseMoveHandler(event : MouseEvent) : void {
            // mouseJointがnullでないときだけ処理を実行する
            if (_mouseJoint) {
                var p2 : b2Vec2 = new b2Vec2(event.stageX / _physScale, event.stageY / _physScale);
                _mouseJoint.SetTarget(p2);               
            }
        }

        private function mouseDownHandler(event : MouseEvent) : void {
            // マウスボタンを押したとき、該当のオブジェクト上にマウスカーソルがあるかを判定
            var body : b2Body = GetBodyAtMouse(event.stageX, event.stageY);
            //mouseJoint = b2MouseJoint(world.CreateJoint(mouseJointDef));
            if (body) {
                var md : b2MouseJointDef = new b2MouseJointDef();
                md.body1 = _world.m_groundBody;
                md.body2 = body;
                md.target.Set(event.stageX / _physScale, event.stageY / _physScale);
                md.maxForce = 500.0 * body.m_mass;
                md.timeStep = _timeStep;
                _mouseJoint = _world.CreateJoint(md) as b2MouseJoint;
                body.WakeUp();
            }
        }

        private function mouseUpHandler(event : MouseEvent) : void {
            // マウスボタンが離されたら,マウスボタンを切り離す
            if(_mouseJoint){
                _world.DestroyJoint(_mouseJoint);
                _mouseJoint = null;            
            }
        }

        //該当オブジェクトがあるかの判定
        private function GetBodyAtMouse(stageX : Number, stageY : Number) : b2Body {
            // Make a small box.
            var mousePVec : b2Vec2 = new b2Vec2();
            var mouseXWorldPhys : Number = stageX / _physScale;
            var mouseYWorldPhys : Number = stageY / _physScale;

            mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
            var aabb : b2AABB = new b2AABB();
            aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
            aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
    
            // Query the world for overlapping shapes.
            var k_maxCount : int = 10;
            var shapes : Array = new Array();
            var count : int = _world.Query(aabb, shapes, k_maxCount);
            var body : b2Body = null;
            for (var i : int = 0;i < count; ++i) {
                if (shapes[i].m_body.IsStatic() == false) {
                    var tShape : b2Shape = shapes[i] as b2Shape;
                    var inside : Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
                    if (inside) {
                        body = tShape.m_body;
                        break;
                    }
                }
            }
            return body;
        }

        
        private function EnterFrame(event : Event) : void {
    
            _world.Step(_timeStep, _iterations);
            
            //画面外に行ったオブジェクトを削除する
            var marginX : Number = 100;
            var marginY : Number = 100;
            for (var b : b2Body = _world.GetBodyList();b; b = b.GetNext()) {
                var xPos : Number = b.GetWorldCenter().x * _physScale;
                var yPos : Number = b.GetWorldCenter().y * _physScale;
                if (!b.m_userData && (xPos > stage.stageWidth + marginX || xPos < -marginX || yPos > stage.stageHeight + marginY)) {
                    //マウスジョイントがある場合
                    if(_mouseJoint) {
                        if(_mouseJoint.m_body2 == b) {
                            _world.DestroyJoint(_mouseJoint);
                            _mouseJoint = null;            
                        }
                    }
                    _world.DestroyBody(b);
                }
            }        
        }


        // 物体を1個作る
        private function createObject(mx : Number = 0,my : Number = 0) : void {
            // 物体の定義を作る
            var objBdDef : b2BodyDef = new b2BodyDef();
            objBdDef.position.Set(mx / _physScale, my / _physScale);
            objBdDef.angle = Math.PI / 2 * Math.random();

            // 形の定義を作る
            var shapeDef : b2PolygonDef = new b2PolygonDef();
            shapeDef.SetAsBox(30 / _physScale, 30 / _physScale);
            shapeDef.density = 1;
            shapeDef.restitution = 0.2;
            shapeDef.friction = 0.1;
            
            //サークルを作る
            var circleDef:b2CircleDef = new b2CircleDef();
            circleDef.radius = (0.3 + Math.random());
            circleDef.density = 1;
            circleDef.restitution = 0.4;
            circleDef.friction = 1;
            
            // 物体を作る
            var objBd : b2Body = _world.CreateBody(objBdDef);

            // 形を物体に追加する
            //objBd.CreateShape(shapeDef);
            objBd.CreateShape(circleDef);

            // 重さ・重心を計算する
            objBd.SetMassFromShapes();
        }
        private function addCircle( ax:Number, ay:Number ):void
        {
            //任意の位置にCircleオブジェクト追加してく
            //手順 ShapeなDef→BodyなDef→worldで実体をつくる感じ
            var s:b2CircleDef = new b2CircleDef();
            s.density = 1;
            s.restitution = 0.2;
            s.radius = 0.2;
            
            var b:b2BodyDef = new b2BodyDef();
            b.position.Set( ax, ay );
            
            var bb:b2Body  = _world.CreateBody( b );
            var bs:b2Shape = bb.CreateShape( s );
            bb.SetMassFromShapes();
            
            //Shapeはあとでいじるので配列にいれとく
            bs.m_userData = Number(0);
            //circles.push( b2CircleShape(bs) );
        }
    }
}