flash on 2014-6-7

by tepe
box2dのテスト
Box2D
♥0 | Line 207 | Modified 2014-06-09 13:58:34 | 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/mK7U
 */

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.*;
    
    public class CarFinal extends Sprite {
        // 物理エンジン内の1mを表すためのピクセル数
        private static const DRAW_SCALE:Number = 100;
        // 物理エンジンの管理クラス
        private var world:b2World;
        // 車体
        private var body:b2Body;
        // 前輪
        private var frontWheel:b2Body;
        // 後輪
        private var rearWheel:b2Body;
        // マウスジョイントの定義
        private var mouseJointDef:b2MouseJointDef;
        // マウスジョイント
        private var mouseJoint:b2MouseJoint;
        
        private var txt1:TextField = new TextField();
            
        
        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);
        }
        
        public function CarFinal() {
            ////////////////////////////////////////
            // 物理エンジンのセットアップ
            
            // 外枠を定義する
            var worldAABB:b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-100, -100);
            worldAABB.upperBound.Set(100, 100);
            
            txt1.text = "aaa";
            addChild(txt1);

            var gravity:b2Vec2 = new b2Vec2(0, 9.8);//重力方向
            
            // 外枠と重力を指定して、物理エンジン全体をセットアップする
            world = new b2World(worldAABB, gravity, true);
            debugDraw();
            ////////////////////////////////////////
            // 床の設置
            // 床は画面の下のほうに設置します
            
            // 床の位置を左から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);
            
            // 床の画像を作る
            var floorImage:Sprite = new Sprite();
            floorImage.graphics.lineStyle(1,0x000000);
            floorImage.graphics.beginFill(0xff0000,0.2);
            floorImage.graphics.drawRect(0,0,100,100);
            floorImage.graphics.endFill();
            
            
            //======================
            //▼床(静体)の生成
            //BodyDefの設定
            var bdFloor:b2BodyDef = new b2BodyDef();
            bdFloor.position.Set(2, 2);//初期位置
            //ShapeDefの設定
            var pdFloor:b2PolygonDef = new b2PolygonDef();
            pdFloor.SetAsBox(1.5, 0.15);
            //ボディの生成
            var bFloor:b2Body = world.CreateBody(bdFloor);
            bFloor.CreateShape(pdFloor);
            
            
            
            addBox();
            
            addBall(2);
            
            
            // 画像のサイズを合わせる
            floorImage.width = 4 * DRAW_SCALE;
            floorImage.height = 0.2 * DRAW_SCALE;
            // 床の中心が(0, 0)に来るように,左上にずらす
            floorImage.x = -floorImage.width / 2;
            floorImage.y = -floorImage.height / 2;
            
            // b2BodyのユーザデータとしてSpriteを作る
            floor.m_userData = new Sprite();
            
            // Spriteの場所を物理エンジン内の場所と一致させる
            floor.GetUserData().x = floor.GetWorldCenter().x * DRAW_SCALE;
            floor.GetUserData().y = floor.GetWorldCenter().y * DRAW_SCALE;
            floor.GetUserData().addChild(floorImage);
            addChild(floor.GetUserData());
            
            ////////////////////////////////////////
            // 車体(body)を作る
            // 幅が80cm、高さが20cmで、場所は床の中心から少し上のところ
            
            var bodyDef:b2BodyDef = new b2BodyDef();
            bodyDef.position.Set(2.5, 2);
            
            var bodyShape:b2PolygonDef = new b2PolygonDef();
            bodyShape.SetAsBox(0.4, 0.1);
            bodyShape.density = 1;
            
            body = world.CreateBody(bodyDef);
            body.CreateShape(bodyShape);
            body.SetMassFromShapes();
            
            // 車体の画像を読み込んで表示する
            var bodyImage:Sprite = new Sprite();
            bodyImage.graphics.lineStyle(1,0x000000);
            bodyImage.graphics.beginFill(0x00ff00,0.2);
            bodyImage.graphics.drawRect(0,0,100,100);
            bodyImage.graphics.endFill();
            
            bodyImage.width = 0.8 * DRAW_SCALE;
            bodyImage.height = 0.2 * DRAW_SCALE;
            bodyImage.x = -bodyImage.width / 2;
            bodyImage.y = -bodyImage.height / 2;
            body.m_userData = new Sprite();
            body.GetUserData().x = body.GetWorldCenter().x * DRAW_SCALE;
            body.GetUserData().y = body.GetWorldCenter().y * DRAW_SCALE;
            body.GetUserData().addChild(bodyImage);
            addChild(body.GetUserData());
            
            
            
            ////////////////////////////////////////
            // 前輪(frontWheel)を作る
            
            // bodyDefは再利用できる
            bodyDef.position.Set(2.8, 2);
            
            var wheelShape:b2CircleDef = new b2CircleDef();
            wheelShape.radius = 0.15;
            wheelShape.density = 1;
            
            frontWheel = world.CreateBody(bodyDef);
            frontWheel.CreateShape(wheelShape);
            frontWheel.SetMassFromShapes();
            
            //world.DestroyBody(floor);
            //removeChild(floor.m_userData);
            
            // 前輪の画像を読み込んで表示する
            var frontWheelImage:Sprite = new Sprite();
            frontWheelImage.graphics.lineStyle(1,0x000000);
            frontWheelImage.graphics.beginFill(0x00ffff);
            //frontWheelImage.graphics.drawRect(0,0,20,20);
            frontWheelImage.graphics.drawCircle(20,20,20);
            frontWheelImage.graphics.moveTo(20,20);
            frontWheelImage.graphics.lineTo(10,0);
            frontWheelImage.graphics.endFill();
            
            frontWheelImage.width = 0.3 * DRAW_SCALE;
            frontWheelImage.height = 0.3 * DRAW_SCALE;
            frontWheelImage.x = -frontWheelImage.width / 2;
            frontWheelImage.y = -frontWheelImage.height / 2;
            frontWheel.m_userData = new Sprite();
            frontWheel.GetUserData().x = frontWheel.GetWorldCenter().x * DRAW_SCALE;
            frontWheel.GetUserData().y = frontWheel.GetWorldCenter().y * DRAW_SCALE;
            frontWheel.GetUserData().addChild(frontWheelImage);
            addChild(frontWheel.GetUserData());
            
            ////////////////////////////////////////
            // 後輪(rearWheel)を作る
            
            bodyDef.position.Set(2.2, 2);
            
            // wheelShapeも再利用できる
            rearWheel = world.CreateBody(bodyDef);
            rearWheel.CreateShape(wheelShape);
            rearWheel.SetMassFromShapes();
            
            
            // 後輪の画像を読み込んで表示する
            var rearWheelImage:Sprite = new Sprite();
            rearWheelImage.graphics.lineStyle(1,0x000000);
            rearWheelImage.graphics.beginFill(0xffff00);
            rearWheelImage.graphics.drawCircle(20,20,20);
            rearWheelImage.graphics.endFill();
            //線
            rearWheelImage.graphics.moveTo(20,20);
            rearWheelImage.graphics.lineTo(10,0);
            
            rearWheelImage.width = 0.3 * DRAW_SCALE;
            rearWheelImage.height = 0.3 * DRAW_SCALE;
            rearWheelImage.x = -rearWheelImage.width / 2;
            rearWheelImage.y = -rearWheelImage.height / 2;
            rearWheel.m_userData = new Sprite();
            rearWheel.GetUserData().x = rearWheel.GetWorldCenter().x * DRAW_SCALE;
            rearWheel.GetUserData().y = rearWheel.GetWorldCenter().y * DRAW_SCALE;
            rearWheel.GetUserData().addChild(rearWheelImage);//
            addChild(rearWheel.GetUserData());
            
            
            
            
            ////////////////////////////////////////
            // 車体と前輪をつなぐ
            
            // ジョイントを定義するjointDef変数
            var jointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
            // つながれる2つの物体と、つなぐ位置(前輪の中央)を使って、定義を初期化する
            jointDef.Initialize(body, frontWheel, frontWheel.GetWorldCenter());
            // 回転速度の設定(6で1秒に1回転ぐらい)
            jointDef.motorSpeed = 3;
            // トルクの設定(大きいほど坂道に強くなる)
            jointDef.maxMotorTorque = 1;
            // 車輪を回すようにする
            //jointDef.enableMotor = true;
            
            // 回転ジョイントを作る
            var frontJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
            
            ////////////////////////////////////////
            // 車体と後輪をつなぐ
            
            // つながれる2つの物体と、つなぐ位置(後輪の中央)を使って、定義を初期化する
            jointDef.Initialize(body, rearWheel, rearWheel.GetWorldCenter());
            
            // 回転ジョイントを作る
            var rearJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
            
            ////////////////////////////////////////
            setMouseJoint();

            
            // イベントハンドラを登録する
            addEventListener(Event.ENTER_FRAME, onFrame);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
        }
        
        private function setMouseJoint():void{
            // マウスジョイントの定義を作る
            
            mouseJointDef = new b2MouseJointDef();
            mouseJointDef.body1 = world.GetGroundBody();
            mouseJointDef.body2 = body;
            mouseJointDef.target = body.GetWorldCenter();
            mouseJointDef.maxForce = 105;
            mouseJointDef.timeStep = 1 / 24;
            
        }
        
        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.9;//反発係数(通常01
            //ボディの生成
            _bBall = world.CreateBody(bdBall);
            _bBall.CreateShape(pdBall);
            //質量の設定
            _bBall.SetMassFromShapes();
        }

        
        private function addBox():void{
            //~~~~~~~~~~~~~~~~▼箱(動体)の生成
            var _bBox:b2Body; 
             
            var bdBox:b2BodyDef = new b2BodyDef();
            bdBox.position.Set(5.5 / 2, 1);
            //ShapeDefの設定
            var pdBox:b2PolygonDef = new b2PolygonDef();
            pdBox.SetAsBox(0.2, 0.2);//形状
            pdBox.density = 10000;//密度(1平方メートルあたりの重量(kg))
            //ボディの生成
            _bBox = world.CreateBody(bdBox);
            _bBox.CreateShape(pdBox);
            //質量の設定
            _bBox.SetMassFromShapes();
        }

 
        
        private function mouseMove(e:MouseEvent):void {
            if (mouseJoint) {
                // マウスが押された場所を物理エンジン内の座標系に変換する
                var x:Number = e.stageX / DRAW_SCALE;
                var y:Number = e.stageY / DRAW_SCALE;
                // マウスジョイントのカーソル位置を更新
                mouseJoint.SetTarget(new b2Vec2(x, y));
            }
        }
        
        private function mouseDown(e:MouseEvent):void {
            mouseJoint = b2MouseJoint(world.CreateJoint(mouseJointDef));
        }
        
        private function mouseUp(event:MouseEvent):void {
            world.DestroyJoint(mouseJoint);
            mouseJoint = null;
        }
        
        //フレーム
        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(body);
                        removeChild(body.m_userData);
                        txt1.text = "Lost";
                    }

                }
            }
        

            
            // Flashはデフォルトで秒間24フレームなので、
            // 物理シミュレーションを1/24秒進める
            world.Step(1 / 24, 10);
        }
    }
}