flutter/packages/flutter_sprites/lib/src/physics_shape.dart

185 lines
5.0 KiB
Dart

part of flutter_sprites;
/// Defines the shape of a [PhysicsBody].
abstract class PhysicsShape {
box2d.Shape _b2Shape;
Object userObject;
box2d.Shape getB2Shape(PhysicsWorld node, double scale) {
if (_b2Shape == null) {
_b2Shape = _createB2Shape(node, scale);
}
return _b2Shape;
}
box2d.Shape _createB2Shape(PhysicsWorld node, double scale);
void _invalidate() {
_b2Shape = null;
}
}
/// Defines a circle shape with a given center [point] and [radius].
///
/// var shape = PhysicsShapeCircle(Point.origin, 20.0);
class PhysicsShapeCircle extends PhysicsShape {
PhysicsShapeCircle(this.point, this.radius);
final Point point;
final double radius;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
box2d.CircleShape shape = new box2d.CircleShape();
shape.p.x = scale * point.x / node.b2WorldToNodeConversionFactor;
shape.p.y = scale * point.y / node.b2WorldToNodeConversionFactor;
shape.radius = scale * radius / node.b2WorldToNodeConversionFactor;
return shape;
}
}
/// 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 {
PhysicsShapePolygon(this.points);
final List<Point> points;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
List<Vector2> vectors = <Vector2>[];
for (Point point in points) {
Vector2 vec = new Vector2(
scale * point.x / node.b2WorldToNodeConversionFactor,
scale * point.y / node.b2WorldToNodeConversionFactor
);
vectors.add(vec);
}
box2d.PolygonShape shape = new box2d.PolygonShape();
shape.set(vectors, vectors.length);
return shape;
}
}
/// Defines a box shape from a [width] and [height].
///
/// var shape = new PhysicsShapeBox(50.0, 100.0);
class PhysicsShapeBox extends PhysicsShape {
PhysicsShapeBox(
this.width,
this.height, [
this.center = Point.origin,
this.rotation = 0.0
]);
final double width;
final double height;
final Point center;
final double rotation;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
box2d.PolygonShape shape = new box2d.PolygonShape();
shape.setAsBox(
scale * width / node.b2WorldToNodeConversionFactor,
scale * height / node.b2WorldToNodeConversionFactor,
new Vector2(
scale * center.x / node.b2WorldToNodeConversionFactor,
scale * center.y / node.b2WorldToNodeConversionFactor
),
radians(rotation)
);
return shape;
}
}
/// 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 {
PhysicsShapeChain(this.points, [this.loop=false]);
final List<Point> points;
final bool loop;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
List<Vector2> vectors = <Vector2>[];
for (Point point in points) {
Vector2 vec = new Vector2(
scale * point.x / node.b2WorldToNodeConversionFactor,
scale * point.y / node.b2WorldToNodeConversionFactor
);
vectors.add(vec);
}
box2d.ChainShape shape = new box2d.ChainShape();
if (loop)
shape.createLoop(vectors, vectors.length);
else
shape.createChain(vectors, vectors.length);
return shape;
}
}
/// 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 {
PhysicsShapeEdge(this.pointA, this.pointB);
final Point pointA;
final Point pointB;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
box2d.EdgeShape shape = new box2d.EdgeShape();
shape.set(
new Vector2(
scale * pointA.x / node.b2WorldToNodeConversionFactor,
scale * pointA.y / node.b2WorldToNodeConversionFactor
),
new Vector2(
scale * pointB.x / node.b2WorldToNodeConversionFactor,
scale * pointB.y / node.b2WorldToNodeConversionFactor
)
);
return shape;
}
}
/// 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 {
PhysicsShapeGroup(this.shapes);
final List<PhysicsShape> shapes;
box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
return null;
}
void _invalidate() {
for (PhysicsShape shape in shapes) {
shape._invalidate();
}
}
}