1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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();
}
}
}