diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 131e7e10..3dc068c2 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -68,4 +68,19 @@ class Ball extends BodyComponent with InitialPosition, Layered { gameRef.spawnBall(); } } + + /// Immediatly and completly [stop]s the ball. + /// + /// The [Ball] will no longer be affected by any forces, including it's + /// weight and those emitted from collisions. + void stop() { + body.setType(BodyType.static); + } + + /// Allows the [Ball] to be affected by forces. + /// + /// If previously [stop]ed, the previous ball's velocity is not kept. + void resume() { + body.setType(BodyType.dynamic); + } } diff --git a/test/game/components/ball_test.dart b/test/game/components/ball_test.dart index 01668d1a..7a48b21f 100644 --- a/test/game/components/ball_test.dart +++ b/test/game/components/ball_test.dart @@ -35,6 +35,26 @@ void main() { expect(ball.body.bodyType, equals(BodyType.dynamic)); }, ); + + group('can be moved', () { + flameTester.test('by its weight', (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + + game.update(1); + expect(ball.body.position, isNot(equals(ball.initialPosition))); + }); + + flameTester.test('by applying velocity', (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + + ball.body.gravityScale = 0; + ball.body.linearVelocity.setValues(10, 10); + game.update(1); + expect(ball.body.position, isNot(equals(ball.initialPosition))); + }); + }); }); group('fixture', () { @@ -151,5 +171,60 @@ void main() { }, ); }); + + group('stop', () { + group("can't be moved", () { + flameTester.test('by its weight', (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + ball.stop(); + + game.update(1); + expect(ball.body.position, equals(ball.initialPosition)); + }); + }); + + flameTester.test('by applying velocity', (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + ball.stop(); + + ball.body.linearVelocity.setValues(10, 10); + game.update(1); + expect(ball.body.position, equals(ball.initialPosition)); + }); + }); + + group('resume', () { + group('can move', () { + flameTester.test( + 'by its weight when previously stopped', + (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + ball.stop(); + ball.resume(); + + game.update(1); + expect(ball.body.position, isNot(equals(ball.initialPosition))); + }, + ); + + flameTester.test( + 'by applying velocity when previously stopped', + (game) async { + final ball = Ball(); + await game.ensureAdd(ball); + ball.stop(); + ball.resume(); + + ball.body.gravityScale = 0; + ball.body.linearVelocity.setValues(10, 10); + game.update(1); + expect(ball.body.position, isNot(equals(ball.initialPosition))); + }, + ); + }); + }); }); }