forked from: Nape 練習

by yurij.shaulov forked from Nape 練習 (diff: 543)
...

@author nekome
♥0 | Line 228 | Modified 2015-06-16 06:45:14 | MIT License | (replaced)
play

ActionScript3 source code

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

// forked from otherone's Nape 練習

package 

{

    import flash.display.Bitmap;

    import flash.display.BitmapData;

    import flash.display.DisplayObject;

    import flash.display.Loader;

    import flash.display.LoaderInfo;



    import flash.events.Event;

    import flash.display.Sprite;

    import flash.events.MouseEvent;

    import flash.net.URLRequest;

    import flash.system.LoaderContext;



    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;



    /**

         * ...

         * @author nekome

         */



    public class Main extends Sprite

    {

        private var space:Space;// 空間

        private var debug:Debug;// デバッグ用

        private var gravity:Vec2;

        private var reverseNum:int = 1;

        private var tongari:Bitmap;

        private var _imgLoader:Loader;

        private var _imgLoaderInfo:LoaderInfo;



        public function Main():void

        {

            // entry point            

            imageLoad();

        }



        private function imageLoad(e:Event = null):void

        {

            //var url:String = "http://works.mztm.jp/moriya/temp/images/tongari.png";

            var url:String = "http://assets.wonderfl.net/images/related_images/9/9b/9b19/9b19a4e0096ca87a11d67620dabd0d50d8b519b6m";

            var urlReq:URLRequest = new URLRequest(url);

            var context:LoaderContext = new LoaderContext();

            context.checkPolicyFile = true;

            _imgLoader = new Loader();

            _imgLoaderInfo = _imgLoader.contentLoaderInfo;

            _imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageloaded);

            _imgLoader.load(urlReq, context);

        }



        private function onImageloaded(e:Event):void

        {

            var bmd:BitmapData = new BitmapData(_imgLoader.width,_imgLoader.height,true,0x00ffffff);

            bmd.draw(_imgLoader);

            tongari = new Bitmap(bmd);

            init();

        }







        public function init():void

        {

            // 空間を作成

            gravity = new Vec2(0,500);// 重力

            space = new Space(gravity);



            // デバッグ表示を設定

            debug = new BitmapDebug(stage.stageWidth,stage.stageHeight,0xFFFFFF);

            addChild(debug.display);



            // 空間に地面を配置

            var floorBody:Body = new Body(BodyType.STATIC);// Body

            var floorShapeTop:Polygon = new Polygon(Polygon.rect(0,-10,stage.width,10));// 形状

            var floorShapeBottom:Polygon = new Polygon(Polygon.rect(0,stage.height - 50,stage.width,50));// 形状

            var floorShapeLeft:Polygon = new Polygon(Polygon.rect(0,0,10,stage.height));// 形状

            var floorShapeRight:Polygon = new Polygon(Polygon.rect(stage.stageWidth - 10,0,10,stage.height));// 形状



            floorBody.shapes.add(floorShapeTop);

            // 形状をBodyへ追加;

            floorBody.shapes.add(floorShapeBottom);

            // 形状をBodyへ追加;

            floorBody.shapes.add(floorShapeLeft);

            // 形状をBodyへ追加;

            floorBody.shapes.add(floorShapeRight);

            // 形状をBodyへ追加;



            space.bodies.add(floorBody);

            // Bodyを空間へ追加;



            // 空間にボールを配置

            var circleBody:Body = new Body();// Body

            var circleShape:Circle = new Circle(50);// 形状

            circleShape.material.elasticity = 1;// 弾力

            circleShape.material.density = 4;// 密度

            circleBody.shapes.add(circleShape);

            // 形状をBodyへ追加;

            circleBody.position.setxy(stage.width/2, 0);

            // 空間内の座標;

            circleBody.velocity.setxy(0, 100);

            // 空間内の初速;

            space.bodies.add(circleBody);

            // Bodyを空間へ追加;



            var playerBody:Body = new Body();// Body

            var squareShape:Polygon = new Polygon(Polygon.rect(0,0,100,100));// 形状

            squareShape.material.elasticity = 3;// 弾力

            squareShape.material.density = 10;// 密度

            playerBody.shapes.add(squareShape);

            // 形状をBodyへ追加;

            playerBody.position.setxy(stage.width/2, 0);

            // 空間内の座標;

            playerBody.velocity.setxy(0, 100);

            // 空間内の初速;

            space.bodies.add(playerBody);

            // Bodyを空間へ追加;



            var cogIso:BitmapDataIso = new BitmapDataIso((tongari).bitmapData, 0x80);

            var cogBody:Body = IsoBody.run(cogIso,cogIso.bounds);



            for (var i:int = 0; i < 2; i++)

            {

                for (var j:int = 0; j < 2; j++)

                {

                    var body:Body = cogBody.copy();

                    body.position.setxy(100 + tongari.width*i, 100+tongari.height*j);

                    body.space = space;

                    var graphic:DisplayObject = cogIso.graphic();

                    //graphic.alpha = 0.6;

                    addChild(graphic);

                    body.userData.graphic = graphic;

                }

            }





            // フレーム処理を開始

            addEventListener(Event.ENTER_FRAME, enterFrameHandler);



            stage.addEventListener(MouseEvent.CLICK, fnClicked);

        }



        private function fnClicked(e:MouseEvent):void

        {

            (reverseNum< 0)?(reverseNum=1):(reverseNum=-1);

            gravity.set(new Vec2(Math.random() * 1000*reverseNum, Math.random() * 1000*reverseNum));

            space.gravity = gravity;

        }



        // フレーム処理

        private function enterFrameHandler(e:Event):void

        {

            // 空間の時間を進めます。

            space.step(1 / stage.frameRate);

            // デバッグ用の表示

            debug.clear();

            debug.draw(space);

            debug.flush();

            for (var i:int = 0; i < space.liveBodies.length; i++)

            {

                var body:Body = space.liveBodies.at(i);

                var graphic:DisplayObject = body.userData.graphic;

                if (graphic == null)

                {

                    continue;

                }

                var graphicOffset:Vec2 = body.userData.graphicOffset;

                var position:Vec2 = body.localPointToWorld(graphicOffset);

                graphic.x = position.x;

                graphic.y = position.y;

                graphic.rotation = (body.rotation * 180/Math.PI) % 360;

                position.dispose();

            }

        }

    }



}











import nape.geom.AABB;



import nape.geom.GeomPoly;



import nape.geom.GeomPolyList;



import nape.geom.IsoFunction;



import nape.geom.MarchingSquares;



import nape.geom.Vec2;



import nape.phys.Body;



import nape.shape.Polygon;







import flash.display.Bitmap;



import flash.display.BitmapData;



import flash.display.DisplayObject;







class IsoBody {;



public static function run(iso:IsoFunction, bounds:AABB, granularity:Vec2=null, quality:int=2, simplification:Number=1.5):Body

{



    var body:Body = new Body();







    if (granularity==null)

    {

        granularity = Vec2.weak(8,8);

    }



    var polys:GeomPolyList = MarchingSquares.run(iso,bounds,granularity,quality);



    for (var i:int = 0; i < polys.length; i++)

    {



        var p:GeomPoly = polys.at(i);







        var qolys:GeomPolyList = p.simplify(simplification).convexDecomposition(true);



        for (var j:int = 0; j < qolys.length; j++)

        {



            var q:GeomPoly = qolys.at(j);







            body.shapes.add(new Polygon(q));







            // Recycle GeomPoly and its vertices



            q.dispose();



        }



        // Recycle list nodes



        qolys.clear();







        // Recycle GeomPoly and its vertices



        p.dispose();



    }



    // Recycle list nodes



    polys.clear();







    // Align body with its centre of mass.



    // Keeping track of our required graphic offset.



    var pivot:Vec2 = body.localCOM.mul(-1);



    body.translateShapes(pivot);







    body.userData.graphicOffset = pivot;



    return body;



}



}







class DisplayObjectIso implements IsoFunction {;



public var displayObject:DisplayObject;



public var bounds:AABB;







public function DisplayObjectIso(displayObject:DisplayObject):void

{



this.displayObject = displayObject;



this.bounds = AABB.fromRect(displayObject.getBounds(displayObject));



}







public function iso(x:Number, y:Number):Number

{



// Best we can really do with a generic DisplayObject



// is to return a binary value {-1, 1} depending on



// if the sample point is in or out side.







return (displayObject.hitTestPoint(x, y, true) ? -1.0 : 1.0);



}



}







class BitmapDataIso implements IsoFunction {;



public var bitmap:BitmapData;



public var alphaThreshold:Number;



public var bounds:AABB;







public function BitmapDataIso(bitmap:BitmapData, alphaThreshold:Number = 0x80):void

{



this.bitmap = bitmap;



this.alphaThreshold = alphaThreshold;



bounds = new AABB(0,0,bitmap.width,bitmap.height);



}







public function graphic():DisplayObject

{



return new Bitmap(bitmap);



}







public function iso(x:Number, y:Number):Number

{



// Take 4 nearest pixels to interpolate linearly.



// This gives us a smooth iso-function for which



// we can use a lower quality in MarchingSquares for



// the root finding.







var ix:int = int(x);

var iy:int = int(y);



//clamp in-case of numerical inaccuracies



if (ix<0)

{

ix = 0;

}

if (iy<0)

{

iy = 0;

}



if (ix>=bitmap.width)

{

ix = bitmap.width - 1;

}



if (iy>=bitmap.height)

{

iy = bitmap.height - 1;

}







// iso-function values at each pixel centre.



var a11:Number = alphaThreshold - (bitmap.getPixel32(ix,iy)>>>24);



var a12:Number = alphaThreshold - (bitmap.getPixel32(ix+1,iy)>>>24);



var a21:Number = alphaThreshold - (bitmap.getPixel32(ix,iy+1)>>>24);



var a22:Number = alphaThreshold - (bitmap.getPixel32(ix+1,iy+1)>>>24);







// Bilinear interpolation for sample point (x,y)



var fx:Number = x - ix;

var fy:Number = y - iy;



return a11*(1-fx)*(1-fy) + a12*fx*(1-fy) + a21*(1-fx)*fy + a22*fx*fy;



}



}