refactor: create fixtures for pathways and opening improved

pull/40/head
RuiAlonso 4 years ago
parent c20c4a550a
commit 9e1b1aa87c

@ -22,7 +22,7 @@ class Baseboard extends BodyComponent with InitialPosition {
final BoardSide _side; final BoardSide _side;
List<FixtureDef> _createFixtureDefs() { List<FixtureDef> _createFixtureDefs() {
final fixtures = <FixtureDef>[]; final fixturesDef = <FixtureDef>[];
final circleShape1 = CircleShape()..radius = Baseboard.height / 2; final circleShape1 = CircleShape()..radius = Baseboard.height / 2;
circleShape1.position.setValues( circleShape1.position.setValues(
@ -30,7 +30,7 @@ class Baseboard extends BodyComponent with InitialPosition {
0, 0,
); );
final circle1FixtureDef = FixtureDef(circleShape1); final circle1FixtureDef = FixtureDef(circleShape1);
fixtures.add(circle1FixtureDef); fixturesDef.add(circle1FixtureDef);
final circleShape2 = CircleShape()..radius = Baseboard.height / 2; final circleShape2 = CircleShape()..radius = Baseboard.height / 2;
circleShape2.position.setValues( circleShape2.position.setValues(
@ -38,7 +38,7 @@ class Baseboard extends BodyComponent with InitialPosition {
0, 0,
); );
final circle2FixtureDef = FixtureDef(circleShape2); final circle2FixtureDef = FixtureDef(circleShape2);
fixtures.add(circle2FixtureDef); fixturesDef.add(circle2FixtureDef);
final rectangle = PolygonShape() final rectangle = PolygonShape()
..setAsBoxXY( ..setAsBoxXY(
@ -46,9 +46,9 @@ class Baseboard extends BodyComponent with InitialPosition {
Baseboard.height / 2, Baseboard.height / 2,
); );
final rectangleFixtureDef = FixtureDef(rectangle); final rectangleFixtureDef = FixtureDef(rectangle);
fixtures.add(rectangleFixtureDef); fixturesDef.add(rectangleFixtureDef);
return fixtures; return fixturesDef;
} }
@override @override

@ -131,7 +131,7 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition {
} }
List<FixtureDef> _createFixtureDefs() { List<FixtureDef> _createFixtureDefs() {
final fixtures = <FixtureDef>[]; final fixturesDef = <FixtureDef>[];
final isLeft = side.isLeft; final isLeft = side.isLeft;
final bigCircleShape = CircleShape()..radius = height / 2; final bigCircleShape = CircleShape()..radius = height / 2;
@ -142,7 +142,7 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition {
0, 0,
); );
final bigCircleFixtureDef = FixtureDef(bigCircleShape); final bigCircleFixtureDef = FixtureDef(bigCircleShape);
fixtures.add(bigCircleFixtureDef); fixturesDef.add(bigCircleFixtureDef);
final smallCircleShape = CircleShape()..radius = bigCircleShape.radius / 2; final smallCircleShape = CircleShape()..radius = bigCircleShape.radius / 2;
smallCircleShape.position.setValues( smallCircleShape.position.setValues(
@ -152,7 +152,7 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition {
0, 0,
); );
final smallCircleFixtureDef = FixtureDef(smallCircleShape); final smallCircleFixtureDef = FixtureDef(smallCircleShape);
fixtures.add(smallCircleFixtureDef); fixturesDef.add(smallCircleFixtureDef);
final trapeziumVertices = isLeft final trapeziumVertices = isLeft
? [ ? [
@ -171,9 +171,9 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition {
final trapeziumFixtureDef = FixtureDef(trapezium) final trapeziumFixtureDef = FixtureDef(trapezium)
..density = 50.0 // TODO(alestiago): Use a proper density. ..density = 50.0 // TODO(alestiago): Use a proper density.
..friction = .1; // TODO(alestiago): Use a proper friction. ..friction = .1; // TODO(alestiago): Use a proper friction.
fixtures.add(trapeziumFixtureDef); fixturesDef.add(trapeziumFixtureDef);
return fixtures; return fixturesDef;
} }
@override @override

@ -17,6 +17,7 @@ class JetpackRamp extends Component with HasGameRef<PinballGame> {
final double _radius = 200; final double _radius = 200;
final double _width = 80; final double _width = 80;
// TODO(ruialonso): Avoid using radians.
final double _angle = radians(210); final double _angle = radians(210);
final double _rotation = radians(-10); final double _rotation = radians(-10);
@ -40,8 +41,9 @@ class JetpackRamp extends Component with HasGameRef<PinballGame> {
radius: _radius, radius: _radius,
angle: _angle, angle: _angle,
rotation: _rotation, rotation: _rotation,
layer: _layer, )
)..initialPosition = position; ..initialPosition = position
..layer = _layer;
final leftOpening = JetpackRampOpening( final leftOpening = JetpackRampOpening(
orientation: RampOrientation.down, orientation: RampOrientation.down,
rotation: radians(15), rotation: radians(15),
@ -84,17 +86,21 @@ class JetpackRampOpening extends RampOpening {
final double _rotation; final double _rotation;
/// Size of the [RampOpening] placed at the entrance/exit of [JetpackRamp]. /// Size of the [RampOpening] placed at the entrance/exit of [JetpackRamp].
final int _size = 6; // TODO(ruialonso): Avoid magic number 3, should be propotional to
// [JetpackRamp].
final Vector2 _size = Vector2(3, .1);
@override @override
RampOrientation get orientation => _orientation; RampOrientation get orientation => _orientation;
@override @override
Shape get shape => PolygonShape() Shape get shape {
..set([ final area = PolygonShape()..setAsBoxXY(_size.x, _size.y);
Vector2(-_size / 2, -.1)..rotate(_rotation), // TODO(alestiago): Use shape.rotate() once it's implemented.
Vector2(-_size / 2, .1)..rotate(_rotation), for (final vertex in area.vertices) {
Vector2(_size / 2, .1)..rotate(_rotation), vertex.rotate(_rotation);
Vector2(_size / 2, -.1)..rotate(_rotation), }
]);
return area;
}
} }

@ -24,6 +24,8 @@ class LauncherRamp extends Component with HasGameRef<PinballGame> {
/// The position of this [LauncherRamp] /// The position of this [LauncherRamp]
final Vector2 position; final Vector2 position;
static const _layer = Layer.launcher;
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
gameRef.addContactCallback( gameRef.addContactCallback(
@ -35,16 +37,18 @@ class LauncherRamp extends Component with HasGameRef<PinballGame> {
start: Vector2(0, 0), start: Vector2(0, 0),
end: Vector2(0, 600), end: Vector2(0, 600),
width: 80, width: 80,
layer: Layer.launcher, )
)..initialPosition = position; ..initialPosition = position
..layer = _layer;
final curvedPath = Pathway.arc( final curvedPath = Pathway.arc(
color: const Color.fromARGB(255, 251, 255, 0), color: const Color.fromARGB(255, 251, 255, 0),
center: position + Vector2(-28.8, -6), center: position + Vector2(-28.8, -6),
radius: _radius, radius: _radius,
angle: _angle, angle: _angle,
width: _width, width: _width,
layer: Layer.launcher, )
)..initialPosition = position + Vector2(-28.8, -6); ..initialPosition = position + Vector2(-28.8, -6)
..layer = _layer;
final leftOpening = LauncherRampOpening( final leftOpening = LauncherRampOpening(
orientation: RampOrientation.down, orientation: RampOrientation.down,
rotation: radians(13), rotation: radians(13),
@ -86,18 +90,22 @@ class LauncherRampOpening extends RampOpening {
/// entrance/exit of [LauncherRamp]. /// entrance/exit of [LauncherRamp].
final double _rotation; final double _rotation;
/// Size of the [RampOpening] placed at the entrance/exit of [LauncherRamp]. /// Size of the [RampOpening] placed at the entrance/exit of [JetpackRamp].
final int _size = 6; // TODO(ruialonso): Avoid magic number 3, should be propotional to
// [JetpackRamp].
final Vector2 _size = Vector2(3, .1);
@override @override
RampOrientation get orientation => _orientation; RampOrientation get orientation => _orientation;
@override @override
Shape get shape => PolygonShape() Shape get shape {
..set([ final area = PolygonShape()..setAsBoxXY(_size.x, _size.y);
Vector2(-_size / 2, -.1)..rotate(_rotation), // TODO(alestiago): Use shape.rotate() once it's implemented.
Vector2(-_size / 2, .1)..rotate(_rotation), for (final vertex in area.vertices) {
Vector2(_size / 2, .1)..rotate(_rotation), vertex.rotate(_rotation);
Vector2(_size / 2, -.1)..rotate(_rotation), }
]);
return area;
}
} }

@ -11,7 +11,7 @@ import 'package:pinball/game/game.dart';
/// bodies with a different bit value. /// bodies with a different bit value.
/// {@endtemplate} /// {@endtemplate}
mixin Layered<T extends Forge2DGame> on BodyComponent<T> { mixin Layered<T extends Forge2DGame> on BodyComponent<T> {
Layer _layer = Layer.board; Layer _layer = Layer.all;
/// Sets [Filter] category and mask bits for the [BodyComponent]. /// Sets [Filter] category and mask bits for the [BodyComponent].
Layer get layer => _layer; Layer get layer => _layer;
@ -19,7 +19,7 @@ mixin Layered<T extends Forge2DGame> on BodyComponent<T> {
set layer(Layer value) { set layer(Layer value) {
_layer = value; _layer = value;
if (!isLoaded) { if (!isLoaded) {
// TODO(erickzanardo): Use loaded.whenComplete once provided. // TODO(alestiago): Use loaded.whenComplete once provided.
mounted.whenComplete(() => layer = value); mounted.whenComplete(() => layer = value);
} else { } else {
for (final fixture in body.fixtures) { for (final fixture in body.fixtures) {

@ -9,14 +9,12 @@ import 'package:pinball/game/game.dart';
/// ///
/// [BodyComponent]s such as a Ball can collide and move along a [Pathway]. /// [BodyComponent]s such as a Ball can collide and move along a [Pathway].
/// {@endtemplate} /// {@endtemplate}
class Pathway extends BodyComponent with InitialPosition { class Pathway extends BodyComponent with InitialPosition, Layered {
Pathway._({ Pathway._({
// TODO(ruialonso): remove color when assets added. // TODO(ruialonso): remove color when assets added.
Color? color, Color? color,
required List<List<Vector2>> paths, required List<List<Vector2>> paths,
Layer? layer, }) : _paths = paths {
}) : _paths = paths,
_layer = layer {
paint = Paint() paint = Paint()
..color = color ?? const Color.fromARGB(0, 0, 0, 0) ..color = color ?? const Color.fromARGB(0, 0, 0, 0)
..style = PaintingStyle.stroke; ..style = PaintingStyle.stroke;
@ -35,7 +33,6 @@ class Pathway extends BodyComponent with InitialPosition {
required double width, required double width,
double rotation = 0, double rotation = 0,
bool singleWall = false, bool singleWall = false,
Layer? layer,
}) { }) {
final paths = <List<Vector2>>[]; final paths = <List<Vector2>>[];
@ -57,7 +54,6 @@ class Pathway extends BodyComponent with InitialPosition {
return Pathway._( return Pathway._(
color: color, color: color,
paths: paths, paths: paths,
layer: layer,
); );
} }
@ -81,7 +77,6 @@ class Pathway extends BodyComponent with InitialPosition {
required double angle, required double angle,
double rotation = 0, double rotation = 0,
bool singleWall = false, bool singleWall = false,
Layer? layer,
}) { }) {
final paths = <List<Vector2>>[]; final paths = <List<Vector2>>[];
@ -107,7 +102,6 @@ class Pathway extends BodyComponent with InitialPosition {
return Pathway._( return Pathway._(
color: color, color: color,
paths: paths, paths: paths,
layer: layer,
); );
} }
@ -126,7 +120,6 @@ class Pathway extends BodyComponent with InitialPosition {
required double width, required double width,
double rotation = 0, double rotation = 0,
bool singleWall = false, bool singleWall = false,
Layer? layer,
}) { }) {
final paths = <List<Vector2>>[]; final paths = <List<Vector2>>[];
@ -148,28 +141,31 @@ class Pathway extends BodyComponent with InitialPosition {
return Pathway._( return Pathway._(
color: color, color: color,
paths: paths, paths: paths,
layer: layer,
); );
} }
final List<List<Vector2>> _paths; final List<List<Vector2>> _paths;
Layer? _layer;
@override List<FixtureDef> _createFixtureDefs() {
Body createBody() { final fixturesDef = <FixtureDef>[];
final bodyDef = BodyDef()..position = initialPosition;
final body = world.createBody(bodyDef);
for (final path in _paths) { for (final path in _paths) {
final chain = ChainShape() final chain = ChainShape()
..createChain( ..createChain(
path.map(gameRef.screenToWorld).toList(), path.map(gameRef.screenToWorld).toList(),
); );
final fixtureDef = FixtureDef(chain); fixturesDef.add(FixtureDef(chain));
}
body.createFixture(fixtureDef).filterData.categoryBits = return fixturesDef;
_layer?.maskBits ?? Layer.board.maskBits;
} }
@override
Body createBody() {
final bodyDef = BodyDef()..position = initialPosition;
final body = world.createBody(bodyDef);
_createFixtureDefs().forEach(body.createFixture);
return body; return body;
} }
} }

@ -34,7 +34,7 @@ class SlingShot extends BodyComponent with InitialPosition {
static final Vector2 size = Vector2(6, 8); static final Vector2 size = Vector2(6, 8);
List<FixtureDef> _createFixtureDefs() { List<FixtureDef> _createFixtureDefs() {
final fixtures = <FixtureDef>[]; final fixturesDef = <FixtureDef>[];
// TODO(alestiago): This magic number can be deduced by specifying the // TODO(alestiago): This magic number can be deduced by specifying the
// angle and using polar coordinate system to place the bottom right // angle and using polar coordinate system to place the bottom right
@ -65,7 +65,7 @@ class SlingShot extends BodyComponent with InitialPosition {
final triangle = PolygonShape()..set(triangleVertices); final triangle = PolygonShape()..set(triangleVertices);
final triangleFixtureDef = FixtureDef(triangle)..friction = 0; final triangleFixtureDef = FixtureDef(triangle)..friction = 0;
fixtures.add(triangleFixtureDef); fixturesDef.add(triangleFixtureDef);
final kicker = EdgeShape() final kicker = EdgeShape()
..set( ..set(
@ -76,9 +76,9 @@ class SlingShot extends BodyComponent with InitialPosition {
final kickerFixtureDef = FixtureDef(kicker) final kickerFixtureDef = FixtureDef(kicker)
..restitution = 10.0 ..restitution = 10.0
..friction = 0; ..friction = 0;
fixtures.add(kickerFixtureDef); fixturesDef.add(kickerFixtureDef);
return fixtures; return fixturesDef;
} }
@override @override

Loading…
Cancel
Save