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

Nape Samples - FixedDragging

元ネタ: http://napephys.com/samples.html#swf-FixedDragging
Get Adobe Flash player
by Naohiko.Ueno 26 Jan 2013
/**
 * Copyright Naohiko.Ueno ( http://wonderfl.net/user/Naohiko.Ueno )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zaRt
 */

package {

    /**
     *
     * Sample: Fixed Dragging
     * Author: Luca Deltodesco
     *
     * Demonstrating how one might perform a Nape simulation
     * that uses a fixed-time step for better reproducibility.
     * Also demonstrate how to use a PivotJoint for dragging
     * of Nape physics objects.
     *
     */

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.utils.getTimer;

    import nape.constraint.PivotJoint;
    import nape.geom.Vec2;
    import nape.phys.Body;
    import nape.phys.BodyList;
    import nape.phys.BodyType;
    import nape.shape.Circle;
    import nape.shape.Polygon;
    import nape.space.Space;
    import nape.util.BitmapDebug;
    import nape.util.Debug;
    
    [SWF(width="465",height="465",frameRate="60",backgroundColor="#333333")]
    public class FixedDragging extends Sprite {

        private var space:Space;
        private var debug:Debug;
        private var handJoint:PivotJoint;

        private var prevTimeMS:int;
        private var simulationTime:Number;

        public function FixedDragging():void {
            super();

            if (stage != null) {
                initialise(null);
            }
            else {
                addEventListener(Event.ADDED_TO_STAGE, initialise);
            }
        }

        private function initialise(ev:Event):void {
            if (ev != null) {
                removeEventListener(Event.ADDED_TO_STAGE, initialise);
            }

            // Create a new simulation Space.
            //
            //   Default gravity is (0, 0)
            space = new Space();

            // Create a new BitmapDebug screen matching stage dimensions and
            // background colour.
            //
            //   The Debug object itself is not a DisplayObject, we add its
            //   display property to the display list.
            //
            //   We additionally set the flag enabling drawing of constraints
            //   when rendering a Space object to true.
            debug = new BitmapDebug(stage.stageWidth, stage.stageHeight, stage.color);
            addChild(debug.display);
            debug.drawConstraints = true;

            setUp();

            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        private function setUp():void {
            var w:uint = stage.stageWidth;
            var h:uint = stage.stageHeight;

            // Create a static border around stage.
            var border:Body = new Body(BodyType.STATIC);
            border.shapes.add(new Polygon(Polygon.rect(0, 0, w, -1)));
            border.shapes.add(new Polygon(Polygon.rect(0, h, w, 1)));
            border.shapes.add(new Polygon(Polygon.rect(0, 0, -1, h)));
            border.shapes.add(new Polygon(Polygon.rect(w, 0, 1, h)));
            border.space = space;

            // Generate some random objects!
            for (var i:uint = 0; i < 100; i++) {
                var body:Body = new Body();

                // Add random one of either a Circle, Box or Pentagon.
                if (Math.random() < 0.33) {
                    body.shapes.add(new Circle(15));
                }
                else if (Math.random() < 0.5) {
                    body.shapes.add(new Polygon(Polygon.box(25, 25)));
                }
                else {
                    body.shapes.add(new Polygon(Polygon.regular(20, 20, 5)));
                }

                // Set to random position on stage and add to Space.
                body.position.setxy(Math.random() * w, Math.random() * h);
                body.space = space;
            }

            // Set up a PivotJoint constraint for dragging objects.
            //
            //   A PivotJoint constraint has as parameters a pair
            //   of anchor points defined in the local coordinate
            //   system of the respective Bodys which it strives
            //   to lock together, permitting the Bodys to rotate
            //   relative to eachother.
            //
            //   We create a PivotJoint with the first body given
            //   as 'space.world' which is a pre-defined static
            //   body in the Space having no shapes or velocities.
            //   Perfect for dragging objects or pinning things
            //   to the stage.
            //
            //   We do not yet set the second body as this is done
            //   in the mouseDownHandler, so we add to the Space
            //   but set it as inactive.
            handJoint = new PivotJoint(space.world, null, Vec2.weak(), Vec2.weak());
            handJoint.space = space;
            handJoint.active = false;

            // We also define this joint to be 'elastic' by setting
            // its 'stiff' property to false.
            //
            //   We could further configure elastic behaviour of this
            //   constraint through the 'frequency' and 'damping'
            //   properties.
            handJoint.stiff = false;

            // Set up fixed time step logic.
            prevTimeMS = getTimer();
            simulationTime = 0.0;
        }

        private function enterFrameHandler(ev:Event):void {

            var curTimeMS:uint = getTimer();
            if (curTimeMS == prevTimeMS) {
                // No time has passed!
                return;
            }

            // Amount of time we need to try and simulate (in seconds).
            var deltaTime:Number = (curTimeMS - prevTimeMS) / 1000;
            // We cap this value so that if execution is paused we do
            // not end up trying to simulate 10 minutes at once.
            if (deltaTime > 0.05) {
                deltaTime = 0.05;
            }
            prevTimeMS = curTimeMS;
            simulationTime += deltaTime;

            // If the hand joint is active, then set its first anchor to be
            // at the mouse coordinates so that we drag bodies that have
            // have been set as the hand joint's body2.
            if (handJoint.active) {
                handJoint.anchor1.setxy(mouseX, mouseY);
            }

            // Keep on stepping forward by fixed time step until amount of time
            // needed has been simulated.
            while (space.elapsedTime < simulationTime) {
                space.step(1 / stage.frameRate);
            }

            // Render Space to the debug draw.
            //   We first clear the debug screen,
            //   then draw the entire Space,
            //   and finally flush the draw calls to the screen.
            debug.clear();
            debug.draw(space);
            debug.flush();
        }

        private function mouseDownHandler(ev:MouseEvent):void {
            // Allocate a Vec2 from object pool.
            var mousePoint:Vec2 = Vec2.get(mouseX, mouseY);

            // Determine the set of Body's which are intersecting mouse point.
            // And search for any 'dynamic' type Body to begin dragging.
            var bodies:BodyList = space.bodiesUnderPoint(mousePoint);
            for (var i:int = 0; i < bodies.length; i++) {
                var body:Body = bodies.at(i);

                if (!body.isDynamic()) {
                    continue;
                }

                // Configure hand joint to drag this body.
                //   We initialise the anchor point on this body so that
                //   constraint is satisfied.
                //
                //   The second argument of worldPointToLocal means we get back
                //   a 'weak' Vec2 which will be automatically sent back to object
                //   pool when setting the handJoint's anchor2 property.
                handJoint.body2 = body;
                handJoint.anchor2.set(body.worldPointToLocal(mousePoint, true));

                // Enable hand joint!
                handJoint.active = true;

                break;
            }

            // Release Vec2 back to object pool.
            mousePoint.dispose();
        }

        private function mouseUpHandler(ev:MouseEvent):void {
            // Disable hand joint (if not already disabled).
            handJoint.active = false;
        }

        private function keyDownHandler(ev:KeyboardEvent):void {
            if (ev.keyCode == 82) { // 'R'
                // space.clear() removes all bodies and constraints from
                // the Space.
                space.clear();

                setUp();
            }
        }
    }
}