forked from: [Box2D][PV3D] JAMPACK MODOKI

by ohisama forked from [Box2D][PV3D] JAMPACK MODOKI (diff: 140)
===================================================

Box23DAS3 and Papervision3D Demo
[Jampack Modoki]
Please drag stage balls

http://yugop.com/ 先生の模倣です。

@author Yasu
@see http://clockmaker.jp/blog/
@since 2009.04.01

===================================================
♥0 | Line 270 | Modified 2013-02-25 15:57:38 | MIT License
play

ActionScript3 source code

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

// forked from clockmaker's [Box2D][PV3D] JAMPACK MODOKI
/*===================================================*//**
 * Box23DAS3 and Papervision3D Demo
 * [Jampack Modoki]
 * Please drag stage balls
 * 
 * http://yugop.com/ 先生の模倣です。
 *
 * @author Yasu
 * @see http://clockmaker.jp/blog/
 * @since 2009.04.01
 *//*===================================================*/
package
{
    import Box2D.Collision.Shapes.*;
    import Box2D.Collision.b2AABB;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.Joints.*;
    import Box2D.Dynamics.*;    
    import flash.net.*;
    import flash.ui.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;    
    import org.papervision3d.events.*;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.view.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.core.geom.renderables.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.materials.special.*;    
    import net.hires.debug.Stats;    
    import flash.utils.Timer;
    import caurina.transitions.Tweener;    
    import jp.progression.casts.CastButton;        
    [SWF(width="450", height="450", frameRate="30", backgroundColor="0")]
    public class Main0 extends BasicView
    {
        static public const SCALE : int = 20;
        static public const OBJ_SIZE:int = 160;
        static public const OBJ_NUM:uint = 13;
        static public const OBJ_COLOR:uint = 0x444444;
        private var worldWidth:Number;
        private var worldHeight:Number;
        private var m_iterations:int;
        private var m_wallWidth:Number;
        private var m_wallHeight:Number;
        private var m_timeStep:Number;
        private var m_physScale:Number;
        private var m_world:b2World;
        private var m_mouseJoint:b2MouseJoint;
        private var m_draggedBody:b2Body;
        private var mouseXWorldPhys:Number;
        private var mouseYWorldPhys:Number;
        private var isMouseDown:Boolean;
        private var arrayIndex:int;
        private var pv3dObjsArr:Vector.<DisplayObject3D> = new Vector.<DisplayObject3D>();
        private var box3dSpapesArr:Vector.<b2Body> = new Vector.<b2Body>();
        private var light:PointLight3D;
        private var mat:FlatShadeMaterial;
        private var timerCnt:int = 0;
        public function Main0() 
        {
            stage.quality = StageQuality.MEDIUM;
            super(450, 450, true, true);
            createPaervision3dWorld();
            createBox2dWorld()
            for (var i : int = 0; i < OBJ_NUM; i++) 
            {
                addObjectAtPv3dWorld();
                addObjectAtBox2dWorld();
            }
            arrayIndex = -1;
            isMouseDown = false;
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            createBackGround();
            cerateFullScreenBtn();
            var timer : Timer = new Timer(1000);
            timer.addEventListener(TimerEvent.TIMER, timerHandler);
            timer.start();            
        }
        private function createPaervision3dWorld() : void
        {
            //camera.zoom = 1000 / camera.focus + 1;
            //camera.x = 0;
            //camera.z = -1000;
            light = new PointLight3D();
            light.z = -100;
            mat = new FlatShadeMaterial(light, OBJ_COLOR);
            mat.interactive = true;
        }
        private function createBox2dWorld() : void
        {
            worldWidth = stage.stageWidth;
            worldHeight = stage.stageHeight;
            m_iterations = 30;
            m_timeStep = 1 / stage.frameRate;
            m_physScale = 60;
            var worldAABB : b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-1000, -1000);
            worldAABB.upperBound.Set(1000, 1000);
            var gravity : b2Vec2 = new b2Vec2(0, 30);
            var doSleep : Boolean = true;
            m_world = new b2World(worldAABB, gravity, doSleep);
            var wallShapeDef : b2PolygonDef = new b2PolygonDef();
            var wallBodyDef : b2BodyDef = new b2BodyDef();
            var wall : b2Body;
            m_wallWidth = stage.stageWidth;
            m_wallHeight = stage.stageHeight * 2;
            wallShapeDef.SetAsBox(10 / m_physScale, m_wallHeight / m_physScale);
            wallBodyDef.position.Set(0, m_wallHeight / 2 / m_physScale);
            wall = m_world.CreateBody(wallBodyDef);
            wall.CreateShape(wallShapeDef);
            wallBodyDef.position.Set(m_wallWidth / m_physScale, m_wallHeight / 2 / m_physScale);
            wall = m_world.CreateBody(wallBodyDef);
            wall.CreateShape(wallShapeDef);
            wallShapeDef.SetAsBox(m_wallWidth / 2 / m_physScale, 10 / m_physScale);
            wallBodyDef.position.Set(m_wallWidth / 2 / m_physScale, -m_wallHeight / 2 / m_physScale);
            wall = m_world.CreateBody(wallBodyDef);
            wall.CreateShape(wallShapeDef);
            wallBodyDef.position.Set(m_wallWidth / 2 / m_physScale, m_wallHeight / 2 / m_physScale);
            wall = m_world.CreateBody(wallBodyDef);
            wall.CreateShape(wallShapeDef);
            wall.SetMassFromShapes();
        }
        private function addObjectAtPv3dWorld() : void
        {
            var size : Number = OBJ_SIZE * Math.random() * 3 / 4 + OBJ_SIZE / 4;
            var obj3d : DisplayObject3D = scene.addChild(new Sphere(mat, size / 2, 6, 5));
            pv3dObjsArr.push(obj3d);
            obj3d.extra = { radius:size, arrayPos:pv3dObjsArr.length - 1 };
            obj3d.x = - 50 * Math.random() + 100;
            obj3d.y = Math.random() * -200 - 200;
            obj3d.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, obj3dMousePressHandler);
            obj3d.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, obj3dMouseOverHandler);
            obj3d.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, obj3dMouseOutHandler);
        }
        private function addObjectAtBox2dWorld() : void
        {
            var obj3d : DisplayObject3D = pv3dObjsArr[pv3dObjsArr.length - 1];
            var circleShape : b2CircleDef = new b2CircleDef();
            circleShape.radius = obj3d.extra.radius / m_physScale / 2;
            circleShape.density = 1;
            circleShape.friction = 0.9;
            circleShape.restitution = 0.7;
            var bodyDef : b2BodyDef = new b2BodyDef();
            bodyDef.position.Set((obj3d.x + worldWidth / 2) / m_physScale, (obj3d.y + worldHeight / 2) / m_physScale);
            var body : b2Body = m_world.CreateBody(bodyDef);
            body.CreateShape(circleShape);
            body.SetUserData(obj3d);
            body.SetMassFromShapes();
            box3dSpapesArr.push(body);
        }
        private function updateMouseWorld() : void
        {
            mouseXWorldPhys = mouseX / m_physScale;
            mouseYWorldPhys = mouseY / m_physScale;
        }
        private function enterFrameHandler(event : Event) : void
        {
            updateMouseWorld();
            mouseDrag();
            m_world.Step(m_timeStep, m_iterations);
            for (var bb : b2Body = m_world.GetBodyList(); bb; bb = bb.GetNext())
            {
                if (bb.GetUserData()is DisplayObject3D)
                {
                    bb.GetUserData().x = bb.GetPosition().x * m_physScale - worldWidth / 2;
                    bb.GetUserData().y = -bb.GetPosition().y * m_physScale + worldHeight / 2;
                    bb.GetUserData().rotationZ = -bb.GetAngle() * (180 / Math.PI);
                }
            }
            singleRender();    
        }
        private function mouseDrag() : void
        {
            if (isMouseDown && ! m_mouseJoint)
            {
                m_draggedBody = null;
                if (arrayIndex > -1) m_draggedBody = box3dSpapesArr[arrayIndex];
                if (m_draggedBody)
                {
                    var md : b2MouseJointDef = new b2MouseJointDef();
                    md.body1 = m_world.GetGroundBody();
                    md.body2 = m_draggedBody;
                    md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
                    md.maxForce = 100000 * m_draggedBody.GetMass();
                    md.timeStep = m_timeStep;
                    m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
                    m_draggedBody.WakeUp();
                }
            }
            if (!isMouseDown)
            {
                if ( m_mouseJoint )
                {
                    m_world.DestroyJoint( m_mouseJoint );
                    m_mouseJoint = null;
                }
            }
            if ( m_mouseJoint )
            {
                var p2 : b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
                m_mouseJoint.SetTarget(p2);
            }
        }
        private function mouseDownHandler(event : MouseEvent) : void
        {
            isMouseDown = true;
        }
        private function mouseUpHandler(event : MouseEvent) : void
        {
            Mouse.cursor = MouseCursor.ARROW;
            isMouseDown = false;
            arrayIndex = -1;
        }
        private function obj3dMousePressHandler(event : InteractiveScene3DEvent):void
        {
            if (arrayIndex == timerCnt) return;
            arrayIndex = (event.target as DisplayObject3D).extra.arrayPos;
        }
        private function obj3dMouseOverHandler(e : InteractiveScene3DEvent):void 
        {
            Mouse.cursor = MouseCursor.HAND;
        }
        private function obj3dMouseOutHandler(e : InteractiveScene3DEvent):void 
        {
            if (!isMouseDown) Mouse.cursor = MouseCursor.ARROW;
        }
        private function timerHandler(e : TimerEvent) : void 
        {
            if (arrayIndex == timerCnt) return;
            Tweener.addTween(pv3dObjsArr[timerCnt],
            {
                scale : 0,
                time  : 0.6,
                transition : "easeInOutExpo",
                onComplete : function():void
                {
                    if (arrayIndex == timerCnt) return;
                    scene.removeChild(pv3dObjsArr[timerCnt]);
                    pv3dObjsArr[timerCnt] = null;
                    m_world.DestroyBody(box3dSpapesArr[timerCnt]);
                    box3dSpapesArr[timerCnt] = null;
                    addObjectAtPv3dWorld();
                    addObjectAtBox2dWorld();
                    timerCnt ++;
                }
            })
        }
        private function createBackGround() : void
        {
            graphics.beginFill(0xffFF0000);
            graphics.drawRect(0, 0, 450, 450);
        }
        private function cerateFullScreenBtn() : void
        {
            var btn:CastButton = new CastButton();
            btn.toolTip.text = "Go Full Screen / Normal Screen";
            //btn.toolTip.delay = 250;
            var loader:Loader = new Loader();
            loader.load(new URLRequest("http://wonderfl.kayac.com/img/code/out_arrow.gif"));
            btn.addChild(loader);
            btn.x = 5;
            btn.y = 5;
            btn.addEventListener(MouseEvent.CLICK, function():void
            {
                if (stage.displayState == StageDisplayState.FULL_SCREEN)
                {
                    stage.quality = StageQuality.MEDIUM;
                    stage.displayState = StageDisplayState.NORMAL;
                }
                else
                {
                    stage.quality = StageQuality.LOW;
                    stage.displayState = StageDisplayState.FULL_SCREEN;
                }
            });
            addChild(btn);
        }
    }
}