diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 738ceec6..d90cca78 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -6,14 +6,9 @@ import 'package:pinball/game/game.dart'; /// A solid, [BodyType.dynamic] sphere that rolls and bounces along the /// [PinballGame]. /// {@endtemplate} -class Ball extends BodyComponent { +class Ball extends BodyComponent with InitialPosition { /// {@macro ball} - Ball({ - required Vector2 position, - }) : _position = position; - - /// The initial position of the [Ball] body. - final Vector2 _position; + Ball(); /// The size of the [Ball] final Vector2 size = Vector2.all(2); @@ -45,7 +40,6 @@ class Ball extends BodyComponent { final bodyDef = BodyDef() ..userData = this - ..position = Vector2(_position.x, _position.y + size.y) ..type = BodyType.dynamic; return world.createBody(bodyDef)..createFixture(fixtureDef); diff --git a/lib/game/components/baseboard.dart b/lib/game/components/baseboard.dart index 60e51593..77f07024 100644 --- a/lib/game/components/baseboard.dart +++ b/lib/game/components/baseboard.dart @@ -6,13 +6,11 @@ import 'package:pinball/game/game.dart'; /// {@template baseboard} /// Straight, angled board piece to corral the [Ball] towards the [Flipper]s. /// {@endtemplate} -class Baseboard extends BodyComponent { +class Baseboard extends BodyComponent with InitialPosition { /// {@macro baseboard} Baseboard({ required BoardSide side, - required Vector2 position, - }) : _side = side, - _position = position; + }) : _side = side; /// The width of the [Baseboard]. static const width = 10.0; @@ -20,9 +18,6 @@ class Baseboard extends BodyComponent { /// The height of the [Baseboard]. static const height = 2.0; - /// The position of the [Baseboard] body. - final Vector2 _position; - /// Whether the [Baseboard] is on the left or right side of the board. final BoardSide _side; @@ -63,7 +58,6 @@ class Baseboard extends BodyComponent { const angle = math.pi / 7; final bodyDef = BodyDef() - ..position = _position ..type = BodyType.static ..angle = _side.isLeft ? -angle : angle; diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart index 674c3e43..b9ea85ea 100644 --- a/lib/game/components/board.dart +++ b/lib/game/components/board.dart @@ -59,24 +59,20 @@ class _BottomGroupSide extends Component { final flipper = Flipper.fromSide( side: _side, - position: _position, - ); - final baseboard = Baseboard( - side: _side, - position: _position + + )..initialPosition = _position; + final baseboard = Baseboard(side: _side) + ..initialPosition = _position + Vector2( (Flipper.width * direction) - direction, Flipper.height, - ), - ); + ); final slingShot = SlingShot( side: _side, - position: _position + - Vector2( - (Flipper.width) * direction, - Flipper.height + SlingShot.size.y, - ), - ); + )..initialPosition = _position + + Vector2( + (Flipper.width) * direction, + Flipper.height + SlingShot.size.y, + ); await addAll([flipper, baseboard, slingShot]); } diff --git a/lib/game/components/bonus_word.dart b/lib/game/components/bonus_word.dart index 49a1da1d..e1078e30 100644 --- a/lib/game/components/bonus_word.dart +++ b/lib/game/components/bonus_word.dart @@ -74,10 +74,9 @@ class BonusWord extends Component with BlocComponent { unawaited( add( BonusLetter( - position: _position - Vector2(16 - (i * 6), -30), letter: letters[i], index: i, - ), + )..initialPosition = _position - Vector2(16 - (i * 6), -30), ), ); } @@ -89,14 +88,12 @@ class BonusWord extends Component with BlocComponent { /// which will activate its letter after contact with a [Ball]. /// {@endtemplate} class BonusLetter extends BodyComponent - with BlocComponent { + with BlocComponent, InitialPosition { /// {@macro bonus_letter} BonusLetter({ - required Vector2 position, required String letter, required int index, - }) : _position = position, - _letter = letter, + }) : _letter = letter, _index = index { paint = Paint()..color = _disableColor; } @@ -107,7 +104,6 @@ class BonusLetter extends BodyComponent static const _activeColor = Colors.green; static const _disableColor = Colors.red; - final Vector2 _position; final String _letter; final int _index; @@ -134,7 +130,6 @@ class BonusLetter extends BodyComponent final bodyDef = BodyDef() ..userData = this - ..position = _position ..type = BodyType.static; return world.createBody(bodyDef)..createFixture(fixtureDef); diff --git a/lib/game/components/flipper.dart b/lib/game/components/flipper.dart index ff4754ea..03875d36 100644 --- a/lib/game/components/flipper.dart +++ b/lib/game/components/flipper.dart @@ -13,19 +13,15 @@ import 'package:pinball/game/game.dart'; /// /// [Flipper] can be controlled by the player in an arc motion. /// {@endtemplate flipper} -class Flipper extends BodyComponent with KeyboardHandler { +class Flipper extends BodyComponent with KeyboardHandler, InitialPosition { /// {@macro flipper} Flipper._({ - required Vector2 position, required this.side, required List keys, - }) : _position = position, - _keys = keys; + }) : _keys = keys; - Flipper._left({ - required Vector2 position, - }) : this._( - position: position, + Flipper._left() + : this._( side: BoardSide.left, keys: [ LogicalKeyboardKey.arrowLeft, @@ -33,10 +29,8 @@ class Flipper extends BodyComponent with KeyboardHandler { ], ); - Flipper._right({ - required Vector2 position, - }) : this._( - position: position, + Flipper._right() + : this._( side: BoardSide.right, keys: [ LogicalKeyboardKey.arrowRight, @@ -50,13 +44,12 @@ class Flipper extends BodyComponent with KeyboardHandler { /// horizontally, also have different [LogicalKeyboardKey]s that control them. factory Flipper.fromSide({ required BoardSide side, - required Vector2 position, }) { switch (side) { case BoardSide.left: - return Flipper._left(position: position); + return Flipper._left(); case BoardSide.right: - return Flipper._right(position: position); + return Flipper._right(); } } @@ -82,9 +75,6 @@ class Flipper extends BodyComponent with KeyboardHandler { /// whereas a [Flipper] with [BoardSide.right] has a clockwise arc motion. final BoardSide side; - /// The initial position of the [Flipper] body. - final Vector2 _position; - /// The [LogicalKeyboardKey]s that will control the [Flipper]. /// /// [onKeyEvent] method listens to when one of these keys is pressed. @@ -200,9 +190,7 @@ class Flipper extends BodyComponent with KeyboardHandler { Body createBody() { final bodyDef = BodyDef() ..gravityScale = 0 - ..type = BodyType.dynamic - ..position = _position; - + ..type = BodyType.dynamic; final body = world.createBody(bodyDef); _createFixtureDefs().forEach(body.createFixture); @@ -238,14 +226,14 @@ class FlipperAnchor extends JointAnchor { /// {@macro flipper_anchor} FlipperAnchor({ required Flipper flipper, - }) : super( - position: Vector2( - flipper.side.isLeft - ? flipper.body.position.x - Flipper.width / 2 - : flipper.body.position.x + Flipper.width / 2, - flipper.body.position.y, - ), - ); + }) { + initialPosition = Vector2( + flipper.side.isLeft + ? flipper.body.position.x - Flipper.width / 2 + : flipper.body.position.x + Flipper.width / 2, + flipper.body.position.y, + ); + } } /// {@template flipper_anchor_revolute_joint_def} diff --git a/lib/game/components/initial_position.dart b/lib/game/components/initial_position.dart index aa4acb46..dc6958d9 100644 --- a/lib/game/components/initial_position.dart +++ b/lib/game/components/initial_position.dart @@ -2,16 +2,28 @@ import 'package:flame_forge2d/flame_forge2d.dart'; /// Forces a given [BodyComponent] to position their [body] to an /// [initialPosition]. +/// +/// Note: If the [initialPosition] is set after the [BodyComponent] has been +/// loaded it will have no effect; defaulting to [Vector2.zero]. mixin InitialPosition on BodyComponent { - /// The initial position of the [body]. - late final Vector2 initialPosition; + final Vector2 _initialPosition = Vector2.zero(); - @override - void onMount() { - super.onMount(); + set initialPosition(Vector2 value) { assert( - body.position == initialPosition, - 'Body position is not equal to initial position.', + !isLoaded, + 'Cannot set initialPosition after component has already loaded.', ); + if (value == initialPosition) return; + + _initialPosition.setFrom(value); + } + + /// The initial position of the [body]. + Vector2 get initialPosition => _initialPosition; + + @override + Future onLoad() async { + await super.onLoad(); + body.position.setFrom(initialPosition); } } diff --git a/lib/game/components/joint_anchor.dart b/lib/game/components/joint_anchor.dart index 05e62b73..36ad3ab0 100644 --- a/lib/game/components/joint_anchor.dart +++ b/lib/game/components/joint_anchor.dart @@ -1,11 +1,12 @@ import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball/game/game.dart'; /// {@template joint_anchor} /// Non visual [BodyComponent] used to hold a [BodyType.dynamic] in [Joint]s /// with this [BodyType.static]. /// -/// It is recommended to [_position] the anchor first and then use the body -/// position as the anchor point when initializing a [JointDef]. +/// It is recommended to use [JointAnchor.body.position] to position the anchor +/// point when initializing a [JointDef]. /// /// ```dart /// initialize( @@ -15,18 +16,12 @@ import 'package:flame_forge2d/flame_forge2d.dart'; /// ); /// ``` /// {@endtemplate} -class JointAnchor extends BodyComponent { +class JointAnchor extends BodyComponent with InitialPosition { /// {@macro joint_anchor} - JointAnchor({ - required Vector2 position, - }) : _position = position; - - final Vector2 _position; + JointAnchor(); @override Body createBody() { - final bodyDef = BodyDef()..position = _position; - - return world.createBody(bodyDef); + return world.createBody(BodyDef()); } } diff --git a/lib/game/components/pathway.dart b/lib/game/components/pathway.dart index d41ce3da..bd8caf5d 100644 --- a/lib/game/components/pathway.dart +++ b/lib/game/components/pathway.dart @@ -2,20 +2,19 @@ import 'package:flame/extensions.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; import 'package:geometry/geometry.dart'; +import 'package:pinball/game/game.dart'; /// {@template pathway} /// [Pathway] creates lines of various shapes. /// /// [BodyComponent]s such as a Ball can collide and move along a [Pathway]. /// {@endtemplate} -class Pathway extends BodyComponent { +class Pathway extends BodyComponent with InitialPosition { Pathway._({ // TODO(ruialonso): remove color when assets added. Color? color, - required Vector2 position, required List> paths, - }) : _position = position, - _paths = paths { + }) : _paths = paths { paint = Paint() ..color = color ?? const Color.fromARGB(0, 0, 0, 0) ..style = PaintingStyle.stroke; @@ -23,14 +22,12 @@ class Pathway extends BodyComponent { /// Creates a uniform unidirectional (straight) [Pathway]. /// - /// Does so with two [ChainShape] separated by a [width]. Placed - /// at a [position] between [start] and [end] points. Can + /// Does so with two [ChainShape] separated by a [width]. Can /// be rotated by a given [rotation] in radians. /// /// If [singleWall] is true, just one [ChainShape] is created. factory Pathway.straight({ Color? color, - required Vector2 position, required Vector2 start, required Vector2 end, required double width, @@ -56,28 +53,25 @@ class Pathway extends BodyComponent { return Pathway._( color: color, - position: position, paths: paths, ); } /// Creates an arc [Pathway]. /// - /// The [angle], in radians, specifies the size of the arc. For example, 2*pi - /// returns a complete circumference and minor angles a semi circumference. - /// - /// The center of the arc is placed at [position]. + /// The [angle], in radians, specifies the size of the arc. For example, two + /// pi returns a complete circumference. /// /// Does so with two [ChainShape] separated by a [width]. Which can be /// rotated by a given [rotation] in radians. /// /// The outer radius is specified by [radius], whilst the inner one is - /// equivalent to [radius] - [width]. + /// equivalent to the [radius] minus the [width]. /// /// If [singleWall] is true, just one [ChainShape] is created. factory Pathway.arc({ Color? color, - required Vector2 position, + required Vector2 center, required double width, required double radius, required double angle, @@ -88,7 +82,7 @@ class Pathway extends BodyComponent { // TODO(ruialonso): Refactor repetitive logic final outerWall = calculateArc( - center: position, + center: center, radius: radius, angle: angle, offsetAngle: rotation, @@ -97,7 +91,7 @@ class Pathway extends BodyComponent { if (!singleWall) { final innerWall = calculateArc( - center: position, + center: center, radius: radius - width, angle: angle, offsetAngle: rotation, @@ -107,7 +101,6 @@ class Pathway extends BodyComponent { return Pathway._( color: color, - position: position, paths: paths, ); } @@ -123,7 +116,6 @@ class Pathway extends BodyComponent { /// If [singleWall] is true, just one [ChainShape] is created. factory Pathway.bezierCurve({ Color? color, - required Vector2 position, required List controlPoints, required double width, double rotation = 0, @@ -148,20 +140,15 @@ class Pathway extends BodyComponent { return Pathway._( color: color, - position: position, paths: paths, ); } - final Vector2 _position; final List> _paths; @override Body createBody() { - final bodyDef = BodyDef() - ..type = BodyType.static - ..position = _position; - + final bodyDef = BodyDef()..type = BodyType.static; final body = world.createBody(bodyDef); for (final path in _paths) { final chain = ChainShape() diff --git a/lib/game/components/plunger.dart b/lib/game/components/plunger.dart index 9bcde451..68ccbeb0 100644 --- a/lib/game/components/plunger.dart +++ b/lib/game/components/plunger.dart @@ -9,15 +9,11 @@ import 'package:pinball/game/game.dart'; /// /// [Plunger] ignores gravity so the player controls its downward [_pull]. /// {@endtemplate} -class Plunger extends BodyComponent with KeyboardHandler { +class Plunger extends BodyComponent with KeyboardHandler, InitialPosition { /// {@macro plunger} Plunger({ - required Vector2 position, required this.compressionDistance, - }) : _position = position; - - /// The initial position of the [Plunger] body. - final Vector2 _position; + }); /// Distance the plunger can lower. final double compressionDistance; @@ -30,7 +26,6 @@ class Plunger extends BodyComponent with KeyboardHandler { final bodyDef = BodyDef() ..userData = this - ..position = _position ..type = BodyType.dynamic ..gravityScale = 0; @@ -45,9 +40,9 @@ class Plunger extends BodyComponent with KeyboardHandler { /// Set an upward velocity on the [Plunger]. /// /// The velocity's magnitude depends on how far the [Plunger] has been pulled - /// from its original [_position]. + /// from its original [initialPosition]. void _release() { - final velocity = (_position.y - body.position.y) * 9; + final velocity = (initialPosition.y - body.position.y) * 9; body.linearVelocity = Vector2(0, velocity); } @@ -102,12 +97,12 @@ class PlungerAnchor extends JointAnchor { /// {@macro plunger_anchor} PlungerAnchor({ required Plunger plunger, - }) : super( - position: Vector2( - plunger.body.position.x, - plunger.body.position.y - plunger.compressionDistance, - ), - ); + }) { + initialPosition = Vector2( + plunger.body.position.x, + plunger.body.position.y - plunger.compressionDistance, + ); + } } /// {@template plunger_anchor_prismatic_joint_def} diff --git a/lib/game/components/round_bumper.dart b/lib/game/components/round_bumper.dart index 753ed15b..af8285af 100644 --- a/lib/game/components/round_bumper.dart +++ b/lib/game/components/round_bumper.dart @@ -4,19 +4,14 @@ import 'package:pinball/game/game.dart'; /// {@template round_bumper} /// Circular body that repels a [Ball] on contact, increasing the score. /// {@endtemplate} -class RoundBumper extends BodyComponent with ScorePoints { +class RoundBumper extends BodyComponent with ScorePoints, InitialPosition { /// {@macro round_bumper} RoundBumper({ - required Vector2 position, required double radius, required int points, - }) : _position = position, - _radius = radius, + }) : _radius = radius, _points = points; - /// The position of the [RoundBumper] body. - final Vector2 _position; - /// The radius of the [RoundBumper]. final double _radius; @@ -32,9 +27,7 @@ class RoundBumper extends BodyComponent with ScorePoints { final fixtureDef = FixtureDef(shape)..restitution = 1; - final bodyDef = BodyDef() - ..position = _position - ..type = BodyType.static; + final bodyDef = BodyDef()..type = BodyType.static; return world.createBody(bodyDef)..createFixture(fixtureDef); } diff --git a/lib/game/components/sling_shot.dart b/lib/game/components/sling_shot.dart index 0791cf4f..0002ed0c 100644 --- a/lib/game/components/sling_shot.dart +++ b/lib/game/components/sling_shot.dart @@ -10,22 +10,17 @@ import 'package:pinball/game/game.dart'; /// /// [SlingShot]s are usually positioned above each [Flipper]. /// {@endtemplate sling_shot} -class SlingShot extends BodyComponent { +class SlingShot extends BodyComponent with InitialPosition { /// {@macro sling_shot} SlingShot({ - required Vector2 position, required BoardSide side, - }) : _position = position, - _side = side { + }) : _side = side { // TODO(alestiago): Use sprite instead of color when provided. paint = Paint() ..color = const Color(0xFF00FF00) ..style = PaintingStyle.fill; } - /// The initial position of the [SlingShot] body. - final Vector2 _position; - /// Whether the [SlingShot] is on the left or right side of the board. /// /// A [SlingShot] with [BoardSide.left] propels the [Ball] to the right, @@ -88,8 +83,7 @@ class SlingShot extends BodyComponent { @override Body createBody() { - final bodyDef = BodyDef()..position = _position; - final body = world.createBody(bodyDef); + final body = world.createBody(BodyDef()); _createFixtureDefs().forEach(body.createFixture); return body; diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 112f0522..61ef17e0 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -78,7 +78,11 @@ class PinballGame extends Forge2DGame } void spawnBall() { - add(Ball(position: plunger.body.position)); + final ball = Ball(); + add( + ball + ..initialPosition = plunger.body.position + Vector2(0, ball.size.y / 2), + ); } void _addContactCallbacks() { @@ -93,19 +97,17 @@ class PinballGame extends Forge2DGame } Future _addPlunger() async { - final compressionDistance = camera.viewport.effectiveSize.y / 12; - - await add( - plunger = Plunger( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 1.035, - camera.viewport.effectiveSize.y - compressionDistance, - ), - ), - compressionDistance: compressionDistance, + plunger = Plunger( + compressionDistance: camera.viewport.effectiveSize.y / 12, + ); + plunger.initialPosition = screenToWorld( + Vector2( + camera.viewport.effectiveSize.x / 1.035, + camera.viewport.effectiveSize.y - plunger.compressionDistance, ), ); + + await add(plunger); } } @@ -114,6 +116,8 @@ class DebugPinballGame extends PinballGame with TapDetector { @override void onTapUp(TapUpInfo info) { - add(Ball(position: info.eventPosition.game)); + add( + Ball()..initialPosition = info.eventPosition.game, + ); } } diff --git a/test/game/components/ball_test.dart b/test/game/components/ball_test.dart index e6172d6d..64d41908 100644 --- a/test/game/components/ball_test.dart +++ b/test/game/components/ball_test.dart @@ -17,7 +17,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ready(); await game.ensureAdd(ball); @@ -26,26 +26,10 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final ball = Ball(position: position); - await game.ensureAdd(ball); - game.contains(ball); - - final expectedPosition = Vector2( - position.x, - position.y + ball.size.y, - ); - expect(ball.body.position, equals(expectedPosition)); - }, - ); - flameTester.test( 'is dynamic', (game) async { - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ensureAdd(ball); expect(ball.body.bodyType, equals(BodyType.dynamic)); @@ -57,7 +41,7 @@ void main() { flameTester.test( 'exists', (game) async { - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ensureAdd(ball); expect(ball.body.fixtures[0], isA()); @@ -67,7 +51,7 @@ void main() { flameTester.test( 'is dense', (game) async { - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ensureAdd(ball); final fixture = ball.body.fixtures[0]; @@ -78,7 +62,7 @@ void main() { flameTester.test( 'shape is circular', (game) async { - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ensureAdd(ball); final fixture = ball.body.fixtures[0]; diff --git a/test/game/components/baseboard_test.dart b/test/game/components/baseboard_test.dart index 8f1874b1..75cc62cc 100644 --- a/test/game/components/baseboard_test.dart +++ b/test/game/components/baseboard_test.dart @@ -15,13 +15,12 @@ void main() { (game) async { await game.ready(); final leftBaseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.left, ); final rightBaseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.right, ); + await game.ensureAddAll([leftBaseboard, rightBaseboard]); expect(game.contains(leftBaseboard), isTrue); @@ -30,28 +29,13 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final baseboard = Baseboard( - position: position, - side: BoardSide.left, - ); - await game.ensureAdd(baseboard); - game.contains(baseboard); - - expect(baseboard.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { final baseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.left, ); + await game.ensureAdd(baseboard); expect(baseboard.body.bodyType, equals(BodyType.static)); @@ -62,11 +46,9 @@ void main() { 'is at an angle', (game) async { final leftBaseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.left, ); final rightBaseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.right, ); await game.ensureAddAll([leftBaseboard, rightBaseboard]); @@ -82,7 +64,6 @@ void main() { 'has three', (game) async { final baseboard = Baseboard( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(baseboard); diff --git a/test/game/components/bonus_word_test.dart b/test/game/components/bonus_word_test.dart index b45bd61a..a9af305e 100644 --- a/test/game/components/bonus_word_test.dart +++ b/test/game/components/bonus_word_test.dart @@ -123,7 +123,6 @@ void main() { 'loads correctly', (game) async { final bonusLetter = BonusLetter( - position: Vector2.zero(), letter: 'G', index: 0, ); @@ -135,27 +134,10 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final bonusLetter = BonusLetter( - position: position, - letter: 'G', - index: 0, - ); - await game.ensureAdd(bonusLetter); - game.contains(bonusLetter); - - expect(bonusLetter.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { final bonusLetter = BonusLetter( - position: Vector2.zero(), letter: 'G', index: 0, ); @@ -171,7 +153,6 @@ void main() { 'exists', (game) async { final bonusLetter = BonusLetter( - position: Vector2.zero(), letter: 'G', index: 0, ); @@ -185,7 +166,6 @@ void main() { 'is sensor', (game) async { final bonusLetter = BonusLetter( - position: Vector2.zero(), letter: 'G', index: 0, ); @@ -200,7 +180,6 @@ void main() { 'shape is circular', (game) async { final bonusLetter = BonusLetter( - position: Vector2.zero(), letter: 'G', index: 0, ); diff --git a/test/game/components/flipper_test.dart b/test/game/components/flipper_test.dart index eae238c9..e6e9ba23 100644 --- a/test/game/components/flipper_test.dart +++ b/test/game/components/flipper_test.dart @@ -22,11 +22,9 @@ void main() { (game) async { final leftFlipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); final rightFlipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); await game.ready(); await game.ensureAddAll([leftFlipper, rightFlipper]); @@ -40,41 +38,23 @@ void main() { test('sets BoardSide', () { final leftFlipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); expect(leftFlipper.side, equals(leftFlipper.side)); final rightFlipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); expect(rightFlipper.side, equals(rightFlipper.side)); }); }); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final flipper = Flipper.fromSide( - side: BoardSide.left, - position: position, - ); - await game.ensureAdd(flipper); - game.contains(flipper); - - expect(flipper.body.position, position); - }, - ); - flameTester.test( 'is dynamic', (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -87,7 +67,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -100,9 +79,8 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); - final ball = Ball(position: Vector2.zero()); + final ball = Ball(); await game.ready(); await game.ensureAddAll([flipper, ball]); @@ -121,7 +99,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -134,7 +111,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -165,7 +141,6 @@ void main() { setUp(() { flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); }); @@ -232,7 +207,6 @@ void main() { setUp(() { flipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); }); @@ -302,7 +276,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -318,7 +291,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -337,7 +309,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -359,7 +330,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -380,7 +350,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -406,7 +375,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.left, - position: Vector2.zero(), ); await game.ensureAdd(flipper); @@ -433,7 +401,6 @@ void main() { (game) async { final flipper = Flipper.fromSide( side: BoardSide.right, - position: Vector2.zero(), ); await game.ensureAdd(flipper); diff --git a/test/game/components/initial_position_test.dart b/test/game/components/initial_position_test.dart index 393d780a..814b1e86 100644 --- a/test/game/components/initial_position_test.dart +++ b/test/game/components/initial_position_test.dart @@ -12,13 +12,6 @@ class TestBodyComponent extends BodyComponent with InitialPosition { } } -class TestPositionedBodyComponent extends BodyComponent with InitialPosition { - @override - Body createBody() { - return world.createBody(BodyDef()..position = initialPosition); - } -} - void main() { final flameTester = FlameTester(Forge2DGame.new); group('InitialPosition', () { @@ -27,37 +20,36 @@ void main() { expect(component.initialPosition, Vector2(1, 2)); }); - test('can only be set once', () { - final component = TestBodyComponent()..initialPosition = Vector2(1, 2); - expect( - () => component.initialPosition = Vector2(3, 4), - throwsA(isA()), - ); - }); - flameTester.test( - 'returns normally ' - 'when the body sets the position to initial position', + 'positions correctly', (game) async { - final component = TestPositionedBodyComponent() - ..initialPosition = Vector2.zero(); + final position = Vector2.all(10); + final component = TestBodyComponent()..initialPosition = position; + await game.ensureAdd(component); + expect(component.body.position, equals(position)); + }, + ); - await expectLater( - () async => game.ensureAdd(component), - returnsNormally, - ); + flameTester.test( + 'deafaults to zero ' + 'when no initialPosition is given', + (game) async { + final component = TestBodyComponent(); + await game.ensureAdd(component); + expect(component.body.position, equals(Vector2.zero())); }, ); flameTester.test( - 'throws AssertionError ' - 'when not setting initialPosition to body', + 'setting throws AssertionError ' + 'when component has loaded', (game) async { - final component = TestBodyComponent()..initialPosition = Vector2.zero(); + final component = TestBodyComponent(); await game.ensureAdd(component); - await expectLater( - () async => game.ensureAdd(component), + expect(component.isLoaded, isTrue); + expect( + () => component.initialPosition = Vector2.all(4), throwsAssertionError, ); }, diff --git a/test/game/components/joint_anchor_test.dart b/test/game/components/joint_anchor_test.dart index 8278d43a..652bd445 100644 --- a/test/game/components/joint_anchor_test.dart +++ b/test/game/components/joint_anchor_test.dart @@ -13,7 +13,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { - final anchor = JointAnchor(position: Vector2.zero()); + final anchor = JointAnchor(); await game.ready(); await game.ensureAdd(anchor); @@ -22,24 +22,11 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - await game.ready(); - final position = Vector2.all(10); - final anchor = JointAnchor(position: position); - await game.ensureAdd(anchor); - game.contains(anchor); - - expect(anchor.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { await game.ready(); - final anchor = JointAnchor(position: Vector2.zero()); + final anchor = JointAnchor(); await game.ensureAdd(anchor); expect(anchor.body.bodyType, equals(BodyType.static)); @@ -51,7 +38,7 @@ void main() { flameTester.test( 'has none', (game) async { - final anchor = JointAnchor(position: Vector2.zero()); + final anchor = JointAnchor(); await game.ensureAdd(anchor); expect(anchor.body.fixtures, isEmpty); diff --git a/test/game/components/pathway_test.dart b/test/game/components/pathway_test.dart index 80c968d8..550714cb 100644 --- a/test/game/components/pathway_test.dart +++ b/test/game/components/pathway_test.dart @@ -20,7 +20,6 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.straight( - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -44,7 +43,6 @@ void main() { final pathway = Pathway.straight( color: defaultColor, - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -63,7 +61,6 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.straight( - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -75,30 +72,11 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - await game.ready(); - final position = Vector2.all(10); - final pathway = Pathway.straight( - position: position, - start: Vector2(10, 10), - end: Vector2(20, 20), - width: width, - ); - await game.ensureAdd(pathway); - - game.contains(pathway); - expect(pathway.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { await game.ready(); final pathway = Pathway.straight( - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -116,7 +94,6 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.straight( - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -136,7 +113,6 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.straight( - position: Vector2.zero(), start: Vector2(10, 10), end: Vector2(20, 20), width: width, @@ -159,7 +135,7 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.arc( - position: Vector2.zero(), + center: Vector2.zero(), width: width, radius: 100, angle: math.pi / 2, @@ -171,30 +147,12 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - await game.ready(); - final position = Vector2.all(10); - final pathway = Pathway.arc( - position: position, - width: width, - radius: 100, - angle: math.pi / 2, - ); - await game.ensureAdd(pathway); - - game.contains(pathway); - expect(pathway.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { await game.ready(); final pathway = Pathway.arc( - position: Vector2.zero(), + center: Vector2.zero(), width: width, radius: 100, angle: math.pi / 2, @@ -220,7 +178,6 @@ void main() { (game) async { await game.ready(); final pathway = Pathway.bezierCurve( - position: Vector2.zero(), controlPoints: controlPoints, width: width, ); @@ -231,29 +188,11 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - await game.ready(); - final position = Vector2.all(10); - final pathway = Pathway.bezierCurve( - position: position, - controlPoints: controlPoints, - width: width, - ); - await game.ensureAdd(pathway); - - game.contains(pathway); - expect(pathway.body.position, position); - }, - ); - flameTester.test( 'is static', (game) async { await game.ready(); final pathway = Pathway.bezierCurve( - position: Vector2.zero(), controlPoints: controlPoints, width: width, ); diff --git a/test/game/components/plunger_test.dart b/test/game/components/plunger_test.dart index ecc4265e..1cec7e0c 100644 --- a/test/game/components/plunger_test.dart +++ b/test/game/components/plunger_test.dart @@ -23,7 +23,6 @@ void main() { (game) async { await game.ready(); final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -33,26 +32,10 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final plunger = Plunger( - position: position, - compressionDistance: compressionDistance, - ); - await game.ensureAdd(plunger); - game.contains(plunger); - - expect(plunger.body.position, position); - }, - ); - flameTester.test( 'is dynamic', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -65,7 +48,6 @@ void main() { 'ignores gravity', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -80,7 +62,6 @@ void main() { 'exists', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -93,7 +74,6 @@ void main() { 'shape is a polygon', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -107,7 +87,6 @@ void main() { 'has density', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -129,7 +108,6 @@ void main() { setUp(() { plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); }); @@ -194,7 +172,6 @@ void main() { 'position is a compression distance below the Plunger', (game) async { final plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); await game.ensureAdd(plunger); @@ -222,7 +199,6 @@ void main() { initialState: const GameState.initial(), ); plunger = Plunger( - position: Vector2.zero(), compressionDistance: compressionDistance, ); }); diff --git a/test/game/components/round_bumper_test.dart b/test/game/components/round_bumper_test.dart index c780dd0b..437167ad 100644 --- a/test/game/components/round_bumper_test.dart +++ b/test/game/components/round_bumper_test.dart @@ -18,7 +18,6 @@ void main() { (game) async { await game.ready(); final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); @@ -32,7 +31,6 @@ void main() { 'has points', (game) async { final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); @@ -43,27 +41,10 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final roundBumper = RoundBumper( - position: position, - radius: radius, - points: points, - ); - await game.ensureAdd(roundBumper); - game.contains(roundBumper); - - expect(roundBumper.body.position, equals(position)); - }, - ); - flameTester.test( 'is static', (game) async { final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); @@ -79,7 +60,6 @@ void main() { 'exists', (game) async { final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); @@ -93,7 +73,6 @@ void main() { 'has restitution', (game) async { final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); @@ -108,7 +87,6 @@ void main() { 'shape is circular', (game) async { final roundBumper = RoundBumper( - position: Vector2.zero(), radius: radius, points: points, ); diff --git a/test/game/components/sling_shot_test.dart b/test/game/components/sling_shot_test.dart index e7e89ead..e7c796a1 100644 --- a/test/game/components/sling_shot_test.dart +++ b/test/game/components/sling_shot_test.dart @@ -13,7 +13,6 @@ void main() { 'loads correctly', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -23,25 +22,10 @@ void main() { ); group('body', () { - flameTester.test( - 'positions correctly', - (game) async { - final position = Vector2.all(10); - final slingShot = SlingShot( - position: position, - side: BoardSide.left, - ); - await game.ensureAdd(slingShot); - - expect(slingShot.body.position, equals(position)); - }, - ); - flameTester.test( 'is static', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -56,7 +40,6 @@ void main() { 'exists', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -69,7 +52,6 @@ void main() { 'shape is triangular', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -85,11 +67,9 @@ void main() { 'when side is left or right', (game) async { final leftSlingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); final rightSlingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.right, ); @@ -109,7 +89,6 @@ void main() { 'has no friction', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -125,7 +104,6 @@ void main() { 'exists', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -138,7 +116,6 @@ void main() { 'shape is edge', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -152,7 +129,6 @@ void main() { 'has restitution', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot); @@ -166,7 +142,6 @@ void main() { 'has no friction', (game) async { final slingShot = SlingShot( - position: Vector2.zero(), side: BoardSide.left, ); await game.ensureAdd(slingShot);