forked from: Nape 練習
forked from Nape 練習 (diff: 543)
... @author nekome
♥0 |
Line 228 |
Modified 2015-06-16 06:45:14 |
MIT License
archived:2017-03-20 01:27:52
| (replaced)
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;
}
}