forked from: Papervision3D + BOX2D練習

by takashi08 forked from Papervision3D + BOX2D練習 (diff: 5)
床の上に箱を落とすFlash
♥0 | Line 120 | Modified 2011-01-05 18:11:33 | MIT License
play

ActionScript3 source code

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

// forked from tak0294's Papervision3D + BOX2D練習
package  {
   import Box2D.Collision.b2AABB;
   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.MouseEvent;
    
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.shadematerials.*;
    
    /**
     * 床の上に箱を落とすFlash
     */
    public class Main extends Sprite {
        private var world:b2World;
        private var old_body:b2Body;

        private var body_arr:Array = new Array();
        private var body_arr3d:Array = new Array();
        private var body_count:Number = 0;

        // PV3D用基本変数
        private var viewport:Viewport3D;
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;
        private var rootNode:DisplayObject3D;
        private var light:PointLight3D;
        
        // 床用変数
        private var floorBody1:b2Body;
        private var floor3d:Cube;
        
        public function Main():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);
            ////////////////////////////////////////
            // 描画設定
            
            var debugDraw:b2DebugDraw = new b2DebugDraw();
            debugDraw.m_sprite = this;
            debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
            debugDraw.m_fillAlpha = 1; // 不透明度
            debugDraw.m_lineThickness = 1; // 線の太さ
            //debugDraw.m_drawFlags = 0xFFFFFFFF;
            debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
            world.SetDebugDraw(debugDraw);

            // PV3Dの初期設定
            viewport=new Viewport3D(0, 0, true, true);
            scene=new Scene3D();
            camera=new Camera3D();
            renderer=new BasicRenderEngine();
            rootNode=scene.addChild(new DisplayObject3D("rootNode"));
            camera.zoom=30;
            camera.focus=60;
            camera.x=-400;
            camera.y=400;
            camera.target=DisplayObject3D.ZERO;
            
//            light = new PointLight3D(false);
//            light.z = 0;
//            light.x = -400;
//            light.y = 800;

            addChild(viewport);

            // PV3Dの床の設定
            var boxcolor:Array=new Array();
            for(var i:int=0; i < 6; i++)
            {
            boxcolor[i]=new ColorMaterial(Math.floor(Math.random() * 0xFFFFFF), 0.6);
            }
            var materials:MaterialsList=new MaterialsList({front:boxcolor[0], back:boxcolor[1], right:boxcolor[2], left:boxcolor[3], top:boxcolor[4], bottom:boxcolor[5]});
            floor3d=new Cube(materials, 1000, 100, 10, 4, 4);
            rootNode.addChild(floor3d);
            // イベントハンドラを登録する
            stage.addEventListener(MouseEvent.CLICK, clickHandler);
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);

        }
        
        private function clickHandler(event:MouseEvent):void {
            
            ////////////////////////////////////////
            // 箱の設置
            // 箱は床の上から落として、少しはねるようにします
            
            // 箱の位置を左から2.5m、上から1mとする
            var boxBodyDef:b2BodyDef = new b2BodyDef();
            boxBodyDef.position.Set(event.stageX / 100, event.stageY / 100);
            
            // 箱の形を、幅40cm、高さ40cmとして45度ぐらい右に回す
            var boxShapeDef:b2PolygonDef= new b2PolygonDef();
            boxShapeDef.SetAsOrientedBox(0.2, 0.2, new b2Vec2(0, 0), 0);
            boxShapeDef.density = 1;      // 密度 [kg/m^2]
            boxShapeDef.restitution = 0.5;  // 反発係数、通常は0~1
            
            // 箱を動く物体として作る
            var boxBody:b2Body = world.CreateBody(boxBodyDef);
            
            body_arr[body_count] = boxBody;
            /*
            //Jointの作成
            if(old_body != null)
            {
                var distanceJD:b2DistanceJointDef = new b2DistanceJointDef();//まず            jd.body1 = this.old_body;
                //オブジェクトを2つ指定して、固定する位置を指定する。GetPosition()でオブジェクトの中心位置を取得できる。  
                distanceJD.Initialize(boxBody,old_body,boxBody.GetPosition(),old_body.GetPosition());
                
                world.CreateJoint(distanceJD);
            }
            */
            this.old_body = boxBody;
            
            
            boxBody.CreateShape(boxShapeDef);
            boxBody.SetMassFromShapes();
            
            var boxcolor:Array = new Array();
            for(var j:int=0; j < 6; j++)
            {
                boxcolor[j]=new ColorMaterial(0x222222, 1);
            }
            //var materials=new MaterialsList({front:boxcolor[0], back:boxcolor[1], right:boxcolor[2], left:boxcolor[3], top:boxcolor[4], bottom:boxcolor[5]});
            var materials:MaterialsList = new MaterialsList({all:new GouraudMaterial(light,0xFFFFFF,0x666666)}); 
            var cube:Cube=new Cube(materials, 80, 40, 40, 4, 4);
            //マテリアル設定
            
            //var materials = new WireframeMaterial( 0x999999 );
            //materials.doubleSided = true;
            //var spe:Sphere = new Sphere(materials, 40, 8, 6);
            rootNode.addChild(cube, "cube" + body_count.toString());
            
            body_count++;
        }
        
        private function enterFrameHandler(event:Event):void {
            if (world == null) {
                return;
            }
            // Flashはデフォルトで秒間24フレームなので、
            // 物理シミュレーションを1/24秒進める
            world.Step(1 / 24, 10);
            
            camera.x = mouseX * 10;
            camera.y = mouseY * 10;
            
            
            for(var i:int=0; i < body_count; i++)
            {
                var bb:b2Body=body_arr[i]as b2Body;
                //if (bb == boxboy)
                {
                    var cube:Cube=rootNode.getChildByName("cube" + i.toString())as Cube;
                    cube.x=(bb.GetPosition().x) * 100 - 200;
                    cube.y=-(bb.GetPosition().y) * 100 + 300;
                    cube.rotationZ=-bb.GetAngle() * (180 / Math.PI);
                    //break;
                }
            }
            
            
            renderer.renderScene(scene, camera, viewport);
        }
    }
}