Commit 567b0cf2 authored by Viktor Lidholt's avatar Viktor Lidholt

Adds API documentation to sprite physics and renames a few private variables for clarity.

parent af790303
...@@ -786,6 +786,13 @@ class Node { ...@@ -786,6 +786,13 @@ class Node {
PhysicsBody _physicsBody; PhysicsBody _physicsBody;
/// The physics body associated with this node. If a physics body is assigned,
/// and the node is a child of a [PhysicsWorld] or a [PhysicsGroup] the
/// node's position and rotation will be controlled by the body.
///
/// myNode.physicsBody = new PhysicsBody(
/// new PhysicsShapeCircle(Point.zero, 20.0)
/// );
PhysicsBody get physicsBody => _physicsBody; PhysicsBody get physicsBody => _physicsBody;
set physicsBody(PhysicsBody physicsBody) { set physicsBody(PhysicsBody physicsBody) {
......
...@@ -3,7 +3,7 @@ part of flutter_sprites; ...@@ -3,7 +3,7 @@ part of flutter_sprites;
class _PhysicsDebugDraw extends box2d.DebugDraw { class _PhysicsDebugDraw extends box2d.DebugDraw {
_PhysicsDebugDraw( _PhysicsDebugDraw(
box2d.ViewportTransform transform, box2d.ViewportTransform transform,
this.physicsNode this.physicsWorld
) : super(transform) { ) : super(transform) {
appendFlags( appendFlags(
box2d.DebugDraw.JOINT_BIT | box2d.DebugDraw.JOINT_BIT |
...@@ -12,7 +12,7 @@ class _PhysicsDebugDraw extends box2d.DebugDraw { ...@@ -12,7 +12,7 @@ class _PhysicsDebugDraw extends box2d.DebugDraw {
); );
} }
PhysicsWorld physicsNode; PhysicsWorld physicsWorld;
PaintingCanvas canvas; PaintingCanvas canvas;
...@@ -93,12 +93,12 @@ class _PhysicsDebugDraw extends box2d.DebugDraw { ...@@ -93,12 +93,12 @@ class _PhysicsDebugDraw extends box2d.DebugDraw {
Point _toPoint(Vector2 vec) { Point _toPoint(Vector2 vec) {
return new Point( return new Point(
vec.x * physicsNode.b2WorldToNodeConversionFactor, vec.x * physicsWorld.b2WorldToNodeConversionFactor,
vec.y * physicsNode.b2WorldToNodeConversionFactor vec.y * physicsWorld.b2WorldToNodeConversionFactor
); );
} }
double _scale(double value) { double _scale(double value) {
return value * physicsNode.b2WorldToNodeConversionFactor; return value * physicsWorld.b2WorldToNodeConversionFactor;
} }
} }
part of flutter_sprites; part of flutter_sprites;
/// A [Node] that acts as a middle layer between a [PhysicsWorld] and a node
/// with an assigned [PhysicsBody]. The group's transformations are limited to
/// [position], [rotation], and uniform [scale].
///
/// PhysicsGroup group = new PhysicsGroup();
/// myWorld.addChild(group);
/// group.addChild(myNode);
class PhysicsGroup extends Node { class PhysicsGroup extends Node {
set scaleX(double scaleX) { set scaleX(double scaleX) {
......
part of flutter_sprites; part of flutter_sprites;
/// Defines the shape of a [PhysicsBody].
abstract class PhysicsShape { abstract class PhysicsShape {
box2d.Shape _b2Shape; box2d.Shape _b2Shape;
...@@ -20,6 +21,9 @@ abstract class PhysicsShape { ...@@ -20,6 +21,9 @@ abstract class PhysicsShape {
} }
} }
/// Defines a circle shape with a given center [point] and [radius].
///
/// var shape = PhysicsShapeCircle(Point.origin, 20.0);
class PhysicsShapeCircle extends PhysicsShape { class PhysicsShapeCircle extends PhysicsShape {
PhysicsShapeCircle(this.point, this.radius); PhysicsShapeCircle(this.point, this.radius);
...@@ -35,6 +39,14 @@ class PhysicsShapeCircle extends PhysicsShape { ...@@ -35,6 +39,14 @@ class PhysicsShapeCircle extends PhysicsShape {
} }
} }
/// Defines a polygon shape from a list of [points];
///
/// var points = [
/// new Point(-10.0, 0.0),
/// new Point(0.0, 10.0),
/// new Point(10.0, 0.0)
/// ];
/// var shape = new PhysicsShapePolygon(points);
class PhysicsShapePolygon extends PhysicsShape { class PhysicsShapePolygon extends PhysicsShape {
PhysicsShapePolygon(this.points); PhysicsShapePolygon(this.points);
...@@ -56,6 +68,9 @@ class PhysicsShapePolygon extends PhysicsShape { ...@@ -56,6 +68,9 @@ class PhysicsShapePolygon extends PhysicsShape {
} }
} }
/// Defines a box shape from a [width] and [height].
///
/// var shape = new PhysicsShapeBox(50.0, 100.0);
class PhysicsShapeBox extends PhysicsShape { class PhysicsShapeBox extends PhysicsShape {
PhysicsShapeBox( PhysicsShapeBox(
this.width, this.width,
...@@ -84,6 +99,15 @@ class PhysicsShapeBox extends PhysicsShape { ...@@ -84,6 +99,15 @@ class PhysicsShapeBox extends PhysicsShape {
} }
} }
/// Defines a chain shape from a set of [points]. This can be used to create
/// a continuous chain of edges or, if [loop] is set to true, concave polygons.
///
/// var points = [
/// new Point(-10.0, 0.0),
/// new Point(0.0, 10.0),
/// new Point(10.0, 0.0)
/// ];
/// var shape = new PhysicsShapeChain(points);
class PhysicsShapeChain extends PhysicsShape { class PhysicsShapeChain extends PhysicsShape {
PhysicsShapeChain(this.points, [this.loop=false]); PhysicsShapeChain(this.points, [this.loop=false]);
...@@ -109,6 +133,12 @@ class PhysicsShapeChain extends PhysicsShape { ...@@ -109,6 +133,12 @@ class PhysicsShapeChain extends PhysicsShape {
} }
} }
/// Defines a single edge line shape from [pointA] to [pointB].
///
/// var shape = new PhysicsShapeEdge(
/// new Point(20.0, 20.0),
/// new Point(50.0, 20.0)
/// );
class PhysicsShapeEdge extends PhysicsShape { class PhysicsShapeEdge extends PhysicsShape {
PhysicsShapeEdge(this.pointA, this.pointB); PhysicsShapeEdge(this.pointA, this.pointB);
...@@ -131,6 +161,11 @@ class PhysicsShapeEdge extends PhysicsShape { ...@@ -131,6 +161,11 @@ class PhysicsShapeEdge extends PhysicsShape {
} }
} }
/// A group combines several [shapes] into a single shape.
///
/// var s0 = new PhysicsShapeCircle(new Point(-10.0, 0.0), 20.0);
/// var s1 = new PhysicsShapeCircle(new Point(10.0, 0.0), 20.0);
/// var shape = new PhysicsShapeGroup([s0, s1]);
class PhysicsShapeGroup extends PhysicsShape { class PhysicsShapeGroup extends PhysicsShape {
PhysicsShapeGroup(this.shapes); PhysicsShapeGroup(this.shapes);
......
...@@ -9,6 +9,14 @@ enum PhysicsContactType { ...@@ -9,6 +9,14 @@ enum PhysicsContactType {
typedef void PhysicsContactCallback(PhysicsContactType type, PhysicsContact contact); typedef void PhysicsContactCallback(PhysicsContactType type, PhysicsContact contact);
/// A [Node] that performs a 2D physics simulation on any children with a
/// [PhysicsBody] attached. To simulate grand children, they need to be placed
/// in a [PhysicsGroup].
///
/// The PhysicsWorld uses Box2D.dart to perform the actual simulation, but
/// wraps its behavior in a way that is more integrated with the sprite node
/// tree. If needed, you can still access the Box2D world through the [b2World]
/// property.
class PhysicsWorld extends Node { class PhysicsWorld extends Node {
PhysicsWorld(Offset gravity) { PhysicsWorld(Offset gravity) {
b2World = new box2d.World.withGravity( b2World = new box2d.World.withGravity(
...@@ -35,6 +43,7 @@ class PhysicsWorld extends Node { ...@@ -35,6 +43,7 @@ class PhysicsWorld extends Node {
b2World.debugDraw = _debugDraw; b2World.debugDraw = _debugDraw;
} }
/// The Box2D world used to perform the physics simulations.
box2d.World b2World; box2d.World b2World;
_ContactHandler _contactHandler; _ContactHandler _contactHandler;
...@@ -47,14 +56,19 @@ class PhysicsWorld extends Node { ...@@ -47,14 +56,19 @@ class PhysicsWorld extends Node {
List<PhysicsBody> _bodiesScheduledForUpdate = <PhysicsBody>[]; List<PhysicsBody> _bodiesScheduledForUpdate = <PhysicsBody>[];
/// If set to true, a debug image of all physics shapes and joints will
/// be drawn on top of the [SpriteBox].
bool drawDebug = false; bool drawDebug = false;
Matrix4 _debugDrawTransform ; Matrix4 _debugDrawTransform ;
_PhysicsDebugDraw _debugDraw; _PhysicsDebugDraw _debugDraw;
/// The conversion factor that is used to convert points in the physics world
/// node to points in the Box2D physics simulation.
double b2WorldToNodeConversionFactor = 10.0; double b2WorldToNodeConversionFactor = 10.0;
/// The gravity vector used in the simulation.
Offset get gravity { Offset get gravity {
Vector2 g = b2World.getGravity(); Vector2 g = b2World.getGravity();
return new Offset(g.x, g.y); return new Offset(g.x, g.y);
...@@ -66,12 +80,14 @@ class PhysicsWorld extends Node { ...@@ -66,12 +80,14 @@ class PhysicsWorld extends Node {
gravity.dy / b2WorldToNodeConversionFactor)); gravity.dy / b2WorldToNodeConversionFactor));
} }
/// If set to true, objects can fall asleep if the haven't moved in a while.
bool get allowSleep => b2World.isAllowSleep(); bool get allowSleep => b2World.isAllowSleep();
set allowSleep(bool allowSleep) { set allowSleep(bool allowSleep) {
b2World.setAllowSleep(allowSleep); b2World.setAllowSleep(allowSleep);
} }
/// True if sub stepping should be used in the simulation.
bool get subStepping => b2World.isSubStepping(); bool get subStepping => b2World.isSubStepping();
set subStepping(bool subStepping) { set subStepping(bool subStepping) {
...@@ -227,6 +243,26 @@ class PhysicsWorld extends Node { ...@@ -227,6 +243,26 @@ class PhysicsWorld extends Node {
} }
} }
/// Adds a contact callback, the callback will be invoked when bodies collide
/// in the world.
///
/// To match specific sets bodies, use the [tagA] and [tagB]
/// which will be matched to the tag property that is set on the
/// [PhysicsBody]. If [tagA] or [tagB] is set to null, it will match any
/// body.
///
/// By default, callbacks are made at four different times during a
/// collision; preSolve, postSolve, begin, and end. If you are only interested
/// in one of these events you can pass in a [type].
///
/// myWorld.addContactCallback(
/// (PhysicsContactType type, PhysicsContact contact) {
/// print("Collision between ship and asteroid");
/// },
/// "Ship",
/// "Asteroid",
/// PhysicsContactType.begin
/// );
void addContactCallback(PhysicsContactCallback callback, Object tagA, Object tagB, [PhysicsContactType type]) { void addContactCallback(PhysicsContactCallback callback, Object tagA, Object tagB, [PhysicsContactType type]) {
_contactHandler.addContactCallback(callback, tagA, tagB, type); _contactHandler.addContactCallback(callback, tagA, tagB, type);
} }
...@@ -238,12 +274,21 @@ class PhysicsWorld extends Node { ...@@ -238,12 +274,21 @@ class PhysicsWorld extends Node {
super.paint(canvas); super.paint(canvas);
} }
/// Draws the debug data of the physics world, normally this method isn't
/// invoked directly. Instead, set the [drawDebug] property to true.
void paintDebug(PaintingCanvas canvas) { void paintDebug(PaintingCanvas canvas) {
_debugDraw.canvas = canvas; _debugDraw.canvas = canvas;
b2World.drawDebugData(); b2World.drawDebugData();
} }
} }
/// Contains information about a physics collision and is normally passed back
/// in callbacks from the [PhysicsWorld].
///
/// void myCallback(PhysicsContactType type, PhysicsContact contact) {
/// if (contact.isTouching)
/// print("Bodies are touching");
/// }
class PhysicsContact { class PhysicsContact {
PhysicsContact( PhysicsContact(
this.nodeA, this.nodeA,
...@@ -256,13 +301,29 @@ class PhysicsContact { ...@@ -256,13 +301,29 @@ class PhysicsContact {
this.touchingNormal this.touchingNormal
); );
/// The first node as matched in the rules set when adding the callback.
final Node nodeA; final Node nodeA;
/// The second node as matched in the rules set when adding the callback.
final Node nodeB; final Node nodeB;
/// The first shape as matched in the rules set when adding the callback.
final PhysicsShape shapeA; final PhysicsShape shapeA;
/// The second shape as matched in the rules set when adding the callback.
final PhysicsShape shapeB; final PhysicsShape shapeB;
/// True if the two nodes are touching.
final isTouching; final isTouching;
/// To ignore the collision to take place, you can set isEnabled to false
/// during the preSolve phase.
bool isEnabled; bool isEnabled;
/// List of points that are touching, in world coordinates.
final List<Point> touchingPoints; final List<Point> touchingPoints;
/// The normal from [shapeA] to [shapeB] at the touchingPoint.
final Offset touchingNormal; final Offset touchingNormal;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment