From b93e104b0818964d0d7eed0af5a8c9d3b28393b8 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 15 Mar 2022 12:17:49 +0000 Subject: [PATCH 1/2] feat: include boardSide.direction (#46) * feat: implemented BoardSide.direction * docs: included doc comment --- lib/game/components/board_side.dart | 5 +++++ test/game/components/board_side_test.dart | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/lib/game/components/board_side.dart b/lib/game/components/board_side.dart index 611f70b8..ea8fb1cf 100644 --- a/lib/game/components/board_side.dart +++ b/lib/game/components/board_side.dart @@ -19,4 +19,9 @@ extension BoardSideX on BoardSide { /// Whether this side is [BoardSide.right]. bool get isRight => this == BoardSide.right; + + /// Direction of the [BoardSide]. + /// + /// Represents the path which the [BoardSide] moves along. + int get direction => isLeft ? -1 : 1; } diff --git a/test/game/components/board_side_test.dart b/test/game/components/board_side_test.dart index 3d6d3fa1..ba201065 100644 --- a/test/game/components/board_side_test.dart +++ b/test/game/components/board_side_test.dart @@ -23,5 +23,12 @@ void main() { expect(side.isLeft, isFalse); expect(side.isRight, isTrue); }); + + test('direction is correct', () { + const side = BoardSide.left; + expect(side.direction, equals(-1)); + const side2 = BoardSide.right; + expect(side2.direction, equals(1)); + }); }); } From 6a68bf1ed79884c6c218a09e2380cbabeac7f0da Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Tue, 15 Mar 2022 08:34:31 -0500 Subject: [PATCH 2/2] feat: add round bumper (#42) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add round bumper * refactor: PR suggestions * fix: remove unused import 🤦‍♀️ --- lib/game/components/components.dart | 1 + lib/game/components/round_bumper.dart | 41 +++++++ test/game/components/round_bumper_test.dart | 124 ++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 lib/game/components/round_bumper.dart create mode 100644 test/game/components/round_bumper_test.dart diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 71108fcc..f50b62d2 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -6,5 +6,6 @@ export 'flipper.dart'; export 'joint_anchor.dart'; export 'pathway.dart'; export 'plunger.dart'; +export 'round_bumper.dart'; export 'score_points.dart'; export 'wall.dart'; diff --git a/lib/game/components/round_bumper.dart b/lib/game/components/round_bumper.dart new file mode 100644 index 00000000..753ed15b --- /dev/null +++ b/lib/game/components/round_bumper.dart @@ -0,0 +1,41 @@ +import 'package:flame_forge2d/flame_forge2d.dart'; +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 { + /// {@macro round_bumper} + RoundBumper({ + required Vector2 position, + required double radius, + required int points, + }) : _position = position, + _radius = radius, + _points = points; + + /// The position of the [RoundBumper] body. + final Vector2 _position; + + /// The radius of the [RoundBumper]. + final double _radius; + + /// Points awarded from hitting this [RoundBumper]. + final int _points; + + @override + int get points => _points; + + @override + Body createBody() { + final shape = CircleShape()..radius = _radius; + + final fixtureDef = FixtureDef(shape)..restitution = 1; + + final bodyDef = BodyDef() + ..position = _position + ..type = BodyType.static; + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } +} diff --git a/test/game/components/round_bumper_test.dart b/test/game/components/round_bumper_test.dart new file mode 100644 index 00000000..c780dd0b --- /dev/null +++ b/test/game/components/round_bumper_test.dart @@ -0,0 +1,124 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/game/game.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('RoundBumper', () { + final flameTester = FlameTester(Forge2DGame.new); + const radius = 1.0; + const points = 1; + + flameTester.test( + 'loads correctly', + (game) async { + await game.ready(); + final roundBumper = RoundBumper( + position: Vector2.zero(), + radius: radius, + points: points, + ); + await game.ensureAdd(roundBumper); + + expect(game.contains(roundBumper), isTrue); + }, + ); + + flameTester.test( + 'has points', + (game) async { + final roundBumper = RoundBumper( + position: Vector2.zero(), + radius: radius, + points: points, + ); + await game.ensureAdd(roundBumper); + + expect(roundBumper.points, equals(points)); + }, + ); + + 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, + ); + await game.ensureAdd(roundBumper); + + expect(roundBumper.body.bodyType, equals(BodyType.static)); + }, + ); + }); + + group('fixture', () { + flameTester.test( + 'exists', + (game) async { + final roundBumper = RoundBumper( + position: Vector2.zero(), + radius: radius, + points: points, + ); + await game.ensureAdd(roundBumper); + + expect(roundBumper.body.fixtures[0], isA()); + }, + ); + + flameTester.test( + 'has restitution', + (game) async { + final roundBumper = RoundBumper( + position: Vector2.zero(), + radius: radius, + points: points, + ); + await game.ensureAdd(roundBumper); + + final fixture = roundBumper.body.fixtures[0]; + expect(fixture.restitution, greaterThan(0)); + }, + ); + + flameTester.test( + 'shape is circular', + (game) async { + final roundBumper = RoundBumper( + position: Vector2.zero(), + radius: radius, + points: points, + ); + await game.ensureAdd(roundBumper); + + final fixture = roundBumper.body.fixtures[0]; + expect(fixture.shape.shapeType, equals(ShapeType.circle)); + expect(fixture.shape.radius, equals(1)); + }, + ); + }); + }); +}