Nape is a physics engine built in haXe using caXe preprocessor primarily targeting flash player; also tested to compile for hxcpp. It has an incredibly safe and friendly API and features such as general rigid body fluids.
Some other features:
- Rigid bodies built from convex polygons and circles
- Geometric utilities (Verification, Simplification, Convex decomposition, Marching Squares with composition of generated polys).
- Choice of broadphase+sleeping
- Sleeping of objects done without islands for increased effeciency.
- Viewport to evaluate visible objects easily for large physics domains.
- Resting contact with elasticity
- Friction (Dynamic,Static,Rolling*)
- Highly-optimised
- Constraints
- Detailed constraint control with breaking + callbacks
- Callback procedurs for sleeping/waking of bodies and out of bounds behaviour aswell as entry/exit to viewport.
- Callbacks for collisions and sensors to be applied between shape types, object types, and group types.
- Grouping of objects for callback behaviour and exclusion groups
- Query object at position + ray casting
- Evaluation of impact strengths, how much an object is being crushed and an objects stress
Sample
package {
import flash.Boot;
import flash.display.*;
import flash.events.*;
import nape.geom.Vec2;
import nape.phys.Body
import nape.phys.BodyType;
import nape.phys.FluidProperties;
import nape.shape.Shape;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.space.Space;
import nape.util.Debug;
public class Main extends Sprite {
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
new Boot();
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.quality = StageQuality.MEDIUM;
var space:Space = new Space(new Vec2(0, 300));
var debug:Debug = new Debug();
var ground:Body = new Body(BodyType.STATIC);
ground.shapes.add(new Polygon(Polygon.rect(0, 550, 600, 50)));
ground.shapes.add(new Polygon(Polygon.rect(0, 0, 10, 600)));
ground.shapes.add(new Polygon(Polygon.rect(600, 0, -10, 600)));
ground.shapes.add(new Polygon(Polygon.rect(200, 400, 200, 20)));
ground.shapes.add(new Polygon(Polygon.rect(290, 420, 20, 130)));
ground.space = space;
var water:Body = new Body(BodyType.STATIC);
water.shapes.add(new Polygon(Polygon.rect(590, 500, -280, 50)));
water.shapes.add(new Polygon(Polygon.rect(10, 500, 280, 50)));
for (var i:int = 0; i < water.shapes.length; i++) {
var shape:Shape = water.shapes.at(i);
shape.fluidEnabled = true;
shape.fluidProperties = new FluidProperties(4, 10);
}
water.space = space;
for (var y:int = 0; y < 10; y++) {
for (var x:int = 0; x <= 50; x++) {
var box:Body = new Body(BodyType.DYNAMIC, new Vec2(50+x*10,50+y*20));
if ((x+y)%2 == 0) shape = new Polygon(Polygon.regular(10, 20, 4));
else shape = new Circle(5);
shape.body = box;
box.space = space;
}
}
addEventListener(Event.ENTER_FRAME, function (ev:Event):void {
space.step(1 / 60);
graphics.clear();
debug.draw(graphics, space);
});
debug.draw(graphics, space);
}
}
}




