| 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(); |
| } |
| } |
| } |