flash on 2014-6-9

by tepe
♥0 | Line 193 | Modified 2014-10-25 11:52:14 | MIT License
play

ActionScript3 source code

/**
 * Copyright tepe ( http://wonderfl.net/user/tepe )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8P4F
 */

package {
    import Box2D.Collision.b2AABB;
    import Box2D.Collision.Shapes.*;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Dynamics.b2DebugDraw;
    import Box2D.Dynamics.b2World;
    import Box2D.Dynamics.Joints.*;
    
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.ui.*;
    
    public class FlashTest extends Sprite {
        
        private static const DRAW_SCALE:Number = 100;
        // 物理エンジンの管理クラス
        private var world:b2World;
        private var tf:TextField = new TextField();
        
        
        public function FlashTest() {
            
            addChild(tf);
            tf.text = "test";

            // 外枠を定義する
            var worldAABB:b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-100, -100);
            worldAABB.upperBound.Set(100, 100);

            var gravity:b2Vec2 = new b2Vec2(0, 9.8);//重力方向
            
            // 外枠と重力を指定して、物理エンジン全体をセットアップする
            world = new b2World(worldAABB, gravity, true);
            addFloor(2,2);
            debugDraw();
            
            // イベントハンドラを登録する
            addEventListener(Event.ENTER_FRAME, onFrame);
            stage.addEventListener(MouseEvent.CLICK,onClick);
            
        }
        
        
        private function addFloor(x:Number=0,y:Number=0):void{
            var sx:Number = 150;
            var sy:Number = 15;
            //======================
            //▼床(静体)の生成
            //BodyDefの設定
            var bdFloor:b2BodyDef = new b2BodyDef();
            bdFloor.position.Set(x, y);//初期位置
            
            var pdFloor:b2PolygonDef = new b2PolygonDef();//ShapeDefの設定
            pdFloor.SetAsBox(sx/DRAW_SCALE, sy/DRAW_SCALE);
            var bFloor:b2Body = world.CreateBody(bdFloor);//ボディの生成
            bFloor.CreateShape(pdFloor);
            var s:Sprite = createSprite();
            s.name = idCnt.toString();
            idCnt++;
            s.addChild(createLabel("#"+s.name));
            s.graphics.beginFill(0xffff00,0.5);
            s.graphics.drawRect(-sx,-sy,sx*2,sy*2);
            s.graphics.endFill();
            bFloor.m_userData = s;
            addChild(s);
            
        }
        
        private function onClick(e:MouseEvent):void{
            if(Math.random()<0.5)addBall(mouseX/100,mouseY/100);
            else addBox(mouseX/100,mouseY/100);
        }


        
        //フレーム
        private function onFrame(e:Event):void {
            
            // ワールド内の全てのb2Bodyに対する処理
            for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
                if (b.GetUserData() is Sprite) {
                    // 物理エンジン内での位置と回転角度を反映させる
                    b.GetUserData().x = b.GetWorldCenter().x * DRAW_SCALE;
                    b.GetUserData().y = b.GetWorldCenter().y * DRAW_SCALE;
                    b.GetUserData().rotation = b.GetAngle() * 180 / Math.PI;
                    if(b.IsFrozen()){
                        world.DestroyBody(b);
                        removeChild(b.m_userData);
                        tf.appendText(b.m_userData.name+" lost\n");
                        tf.scrollV = tf.maxScrollV;
                        //txt1.text = "Lost";
                    }

                }
            }
            

            
            // Flashはデフォルトで秒間24フレームなので、
            // 物理シミュレーションを1/24秒進める
            world.Step(1 / 24, 10);
        }
        
        private function debugDraw():void {
            var debugDraw:b2DebugDraw = new b2DebugDraw();
            debugDraw.m_sprite = this;
            debugDraw.m_drawScale = DRAW_SCALE;
            debugDraw.m_fillAlpha = 0.3;
            debugDraw.m_lineThickness = 1;
            debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
            world.SetDebugDraw(debugDraw);
        }
        
        private static var idCnt:int=0;
        private function addBall(x:Number=0,y:Number=0):void{
            //▼ボール(動体)の生成------------------
            var _bBall:b2Body;
            var bdBall:b2BodyDef = new b2BodyDef();
            bdBall.position.Set(x,y);
            //ShapeDefの設定
            var pdBall:b2CircleDef = new b2CircleDef();
            pdBall.radius = 0.25;
            pdBall.density = 1;//密度(1平方メートルあたりの重量(kg))
            pdBall.restitution = 0.3;//反発係数(通常01
            //ボディの生成
            _bBall = world.CreateBody(bdBall);
            _bBall.CreateShape(pdBall);
            //質量の設定
            _bBall.SetMassFromShapes();
            
            
            var s:Sprite = createSprite();
            s.name = idCnt.toString();
            idCnt++;
            s.addChild(createLabel("#"+s.name));
            s.graphics.beginFill(0x0000ff,0.5);
            s.graphics.drawCircle(0,0,25);
            s.graphics.endFill();
            s.alpha = 0.5;
            _bBall.m_userData = s;
            addChild(s);
            
            
        }
        
        //ドラッグ操作に対応したSpriteを返す
        private function createSprite():Sprite{
            var s:Sprite = new Sprite();
            s.alpha = 0.5;
            //addChild(s);
            s.addEventListener(MouseEvent.MOUSE_OVER,function():void{//ロールオーバー
                s.alpha = 0.7;
                Mouse.cursor = MouseCursor.HAND;
                stage.removeEventListener(MouseEvent.CLICK,onClick);
            });
            s.addEventListener(MouseEvent.MOUSE_OUT,function():void{//ロールアウト
                s.alpha = 0.5;
                Mouse.cursor = MouseCursor.ARROW;
                stage.addEventListener(MouseEvent.CLICK,onClick);
            });
            s.addEventListener(MouseEvent.MOUSE_DOWN,onDrag);
            s.addEventListener(MouseEvent.MOUSE_UP,onRelease);
            return s;
        }
        
        private function onDrag(e:MouseEvent):void{
            for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
                if (b.GetUserData() is Sprite) {
                    if(b.GetUserData()!=e.currentTarget)continue;
                    if(target!=null){
                        target.WakeUp();
                        target = null;
                    }
                    target = b;
                    tf.appendText(b.m_userData.name+" target\n");
                    break;
                }
            }
            target.PutToSleep();//対象の物理運動を無効
                
            prevX = mouseX;
            prevY = mouseY;
               
            stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
                    
        }
        private function onRelease(e:MouseEvent):void{
            stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMove);
            var vel:b2Vec2 = target.GetLinearVelocity().Copy();
            vel.Add(new b2Vec2(0, 0));//ベクトル設定
            target.SetLinearVelocity(vel);
            target.WakeUp();
            target = null;
        }



        
        private var target:b2Body;//操作対象
        private var prevX:Number;
        private var prevY:Number;
        private function onMove(e:MouseEvent):void{
            
            var mx:Number = mouseX-prevX;
            var my:Number = mouseY-prevY;
            prevX = mouseX;
            prevY = mouseY;
            //target.SetPosition(mouseX,mouseY);
            var curPosition:b2Vec2 = target.GetPosition();
            //curPosition.Add(new b2Vec2(0, -0.5))
            curPosition.Add(new b2Vec2(mx/DRAW_SCALE, my/DRAW_SCALE))
            target.SetXForm(curPosition, target.GetAngle());
            target.PutToSleep();
        }

        
        private function createLabel(str:String):Bitmap{
            var t:TextField = new TextField();
            t.text = str;
            t.selectable=false;
            t.width = t.textWidth+5;
            t.height = t.textHeight+5;
            //t.border=true;
            
            var btm_base:BitmapData = new BitmapData(t.width+1, t.height+1, true, 0xFFFFFF);
            var btm:Bitmap = new Bitmap( btm_base);
            btm_base.draw(t);
            return btm;
        }


        
        private function addBox(x:Number=0,y:Number=0):void{
            //~~~~~~~~~~~~~~~~▼箱(動体)の生成
            var _bBox:b2Body; 
            var sx:Number = 20;
            var sy:Number = 20;
             
            var bdBox:b2BodyDef = new b2BodyDef();
            bdBox.position.Set(x,y);
            //ShapeDefの設定
            var pd:b2PolygonDef = new b2PolygonDef();
            pd.SetAsBox(sx/DRAW_SCALE, sy/DRAW_SCALE);//形状
            pd.density = 10000;//密度(1平方メートルあたりの重量(kg))
            pd.restitution = 0.5;//反発係数(通常01
            //ボディの生成
            _bBox = world.CreateBody(bdBox);
            _bBox.CreateShape(pd);
            //質量の設定
            _bBox.SetMassFromShapes();
            
            //var s:Sprite = new Sprite();
            var s:Sprite = createSprite();
            s.name = idCnt.toString();
            idCnt++;
            s.addChild(createLabel("#"+s.name));
            s.graphics.beginFill(0x00ff00,0.5);
            s.graphics.drawRect(-sx,-sy,sx*2,sy*2);
            s.graphics.endFill();
            _bBox.m_userData = s;
            addChild(s);
        }
        
        
        
    }
    
}

Forked