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