From 338b26a50f638f1368273bae6bb909b8f12de0e0 Mon Sep 17 00:00:00 2001 From: Erick Zanardo Date: Fri, 8 Apr 2022 10:23:38 -0300 Subject: [PATCH] feat: pr suggestions --- lib/game/components/camera_controller.dart | 85 ++++++++++++------- lib/game/components/components.dart | 2 +- ...troller.dart => game_flow_controller.dart} | 2 +- lib/game/pinball_game.dart | 4 +- .../view/widgets/play_button_overlay.dart | 2 +- .../components/camera_controller_test.dart | 26 +++--- ...st.dart => game_flow_controller_test.dart} | 16 ++-- test/game/view/play_button_overlay_test.dart | 12 +-- test/helpers/mocks.dart | 2 +- 9 files changed, 90 insertions(+), 61 deletions(-) rename lib/game/components/{game_controller.dart => game_flow_controller.dart} (95%) rename test/game/components/{game_controller_test.dart => game_flow_controller_test.dart} (86%) diff --git a/lib/game/components/camera_controller.dart b/lib/game/components/camera_controller.dart index faecfb74..e2086cb5 100644 --- a/lib/game/components/camera_controller.dart +++ b/lib/game/components/camera_controller.dart @@ -1,54 +1,81 @@ import 'dart:async'; import 'package:flame/components.dart'; -import 'package:flutter/material.dart'; +import 'package:flame/game.dart'; import 'package:pinball_components/pinball_components.dart'; -/// A [Component] that controls its game camera focus -class CameraController extends Component with HasGameRef, KeyboardHandler { - /// The camera position for the board - @visibleForTesting - static final gamePosition = Vector2(0, -7.8); +/// Adds helpers methods to Flame's [Camera] +extension CameraX on Camera { + /// Instantly apply the point of focus to the [Camera] + void snapToFocus(FocusData data) { + followVector2(data.position); + zoom = data.zoom; + } + + /// Returns a [CameraZoom] that can be added to a [FlameGame] + CameraZoom focusToCameraZoom(FocusData data) { + final zoom = CameraZoom(value: data.zoom); + zoom.completed.then((_) { + moveTo(data.position); + }); + return zoom; + } +} - /// The camera position for the pinball panel - @visibleForTesting - static final backboardPosition = Vector2(0, -100.8); +/// {@template focus_data} +/// Model class that defines a focus point of the camera +/// {@endtemplate} +class FocusData { + /// {@template focus_data} + FocusData({ + required this.zoom, + required this.position, + }); - /// The zoom value for the game mode - @visibleForTesting - late final double gameZoom; + /// The amount of zoom + final double zoom; - /// The zoom value for the panel mode - @visibleForTesting - late final double backboardZoom; + /// The position of the camera + final Vector2 position; +} + +/// A [Component] that controls its game camera focus +class CameraController extends Component with HasGameRef, KeyboardHandler { + /// Holds the data for the game focus point + late final FocusData gameFocus; + + /// Holds the data for the backboard focus point + late final FocusData backboardFocus; @override Future onLoad() async { await super.onLoad(); - gameZoom = gameRef.size.y / 16; - backboardZoom = gameRef.size.y / 18; + final gameZoom = gameRef.size.y / 16; + final backboardZoom = gameRef.size.y / 18; + + gameFocus = FocusData( + zoom: gameZoom, + position: Vector2(0, -7.8), + ); + backboardFocus = FocusData( + zoom: backboardZoom, + position: Vector2(0, -100.8), + ); // Game starts with the camera focused on the panel gameRef.camera ..speed = 100 - ..followVector2(backboardPosition) - ..zoom = backboardZoom; + ..snapToFocus(backboardFocus); } /// Move the camera focus to the game board - Future focusOnGame() async { - final zoom = CameraZoom(value: gameZoom); - unawaited(gameRef.add(zoom)); - await zoom.completed; - gameRef.camera.moveTo(gamePosition); + void focusOnGame() { + gameRef.add(gameRef.camera.focusToCameraZoom(gameFocus)); } /// Move the camera focus to the backboard - Future focusOnBackboard() async { - final zoom = CameraZoom(value: backboardZoom); - unawaited(gameRef.add(zoom)); - await zoom.completed; - gameRef.camera.moveTo(backboardPosition); + void focusOnBackboard() { + gameRef.add(gameRef.camera.focusToCameraZoom(backboardFocus)); } } diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index fe2e610f..6bc65a89 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -4,7 +4,7 @@ export 'camera_controller.dart'; export 'controlled_ball.dart'; export 'controlled_flipper.dart'; export 'flutter_forest.dart'; -export 'game_controller.dart'; +export 'game_flow_controller.dart'; export 'plunger.dart'; export 'score_points.dart'; export 'sparky_fire_zone.dart'; diff --git a/lib/game/components/game_controller.dart b/lib/game/components/game_flow_controller.dart similarity index 95% rename from lib/game/components/game_controller.dart rename to lib/game/components/game_flow_controller.dart index e03f90d1..5a2563ba 100644 --- a/lib/game/components/game_controller.dart +++ b/lib/game/components/game_flow_controller.dart @@ -4,7 +4,7 @@ import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; /// A [Component] that controls the game over and game restart logic -class GameController extends Component +class GameFlowController extends Component with BlocComponent, HasGameRef { @override bool listenWhen(GameState? previousState, GameState newState) { diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 705b5eee..82f70939 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -32,13 +32,13 @@ class PinballGame extends Forge2DGame final PinballAudio audio; - late final GameController gameController; + late final GameFlowController gameFlowController; @override Future onLoad() async { _addContactCallbacks(); - unawaited(add(gameController = GameController())); + unawaited(add(gameFlowController = GameFlowController())); unawaited(add(CameraController())); unawaited(add(Backboard(position: Vector2(0, -88)))); diff --git a/lib/game/view/widgets/play_button_overlay.dart b/lib/game/view/widgets/play_button_overlay.dart index 771e1c32..6f039124 100644 --- a/lib/game/view/widgets/play_button_overlay.dart +++ b/lib/game/view/widgets/play_button_overlay.dart @@ -20,7 +20,7 @@ class PlayButtonOverlay extends StatelessWidget { final l10n = context.l10n; return Center( child: ElevatedButton( - onPressed: _game.gameController.start, + onPressed: _game.gameFlowController.start, child: Text(l10n.play), ), ); diff --git a/test/game/components/camera_controller_test.dart b/test/game/components/camera_controller_test.dart index 8908c574..16d92379 100644 --- a/test/game/components/camera_controller_test.dart +++ b/test/game/components/camera_controller_test.dart @@ -1,7 +1,5 @@ // ignore_for_file: cascade_invocations -import 'dart:async'; - import 'package:flame/game.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -25,28 +23,30 @@ void main() { }); test('correctly calculates the zooms', () async { - expect(controller.gameZoom.toInt(), equals(12)); - expect(controller.backboardZoom.toInt(), equals(11)); + expect(controller.gameFocus.zoom.toInt(), equals(12)); + expect(controller.backboardFocus.zoom.toInt(), equals(11)); }); test('correctly sets the initial zoom and position', () async { - expect(game.camera.zoom, equals(controller.backboardZoom)); - expect(game.camera.follow, equals(CameraController.backboardPosition)); + expect(game.camera.zoom, equals(controller.backboardFocus.zoom)); + expect(game.camera.follow, equals(controller.backboardFocus.position)); }); group('focusOnBoard', () { test('changes the zoom', () async { - unawaited(controller.focusOnGame()); + controller.focusOnGame(); await game.ready(); final zoom = game.firstChild(); expect(zoom, isNotNull); - expect(zoom?.value, equals(controller.gameZoom)); + expect(zoom?.value, equals(controller.gameFocus.zoom)); }); test('moves the camera after the zoom is completed', () async { - final future = controller.focusOnGame(); + controller.focusOnGame(); await game.ready(); + final cameraZoom = game.firstChild()!; + final future = cameraZoom.completed; game.update(10); game.update(0); // Ensure that the component was removed @@ -59,17 +59,19 @@ void main() { group('focusOnBackboard', () { test('changes the zoom', () async { - unawaited(controller.focusOnBackboard()); + controller.focusOnBackboard(); await game.ready(); final zoom = game.firstChild(); expect(zoom, isNotNull); - expect(zoom?.value, equals(controller.backboardZoom)); + expect(zoom?.value, equals(controller.backboardFocus.zoom)); }); test('moves the camera after the zoom is completed', () async { - final future = controller.focusOnBackboard(); + controller.focusOnBackboard(); await game.ready(); + final cameraZoom = game.firstChild()!; + final future = cameraZoom.completed; game.update(10); game.update(0); // Ensure that the component was removed diff --git a/test/game/components/game_controller_test.dart b/test/game/components/game_flow_controller_test.dart similarity index 86% rename from test/game/components/game_controller_test.dart rename to test/game/components/game_flow_controller_test.dart index 3ccda27f..1473d1f4 100644 --- a/test/game/components/game_controller_test.dart +++ b/test/game/components/game_flow_controller_test.dart @@ -10,8 +10,8 @@ import '../../helpers/helpers.dart'; // TODO(erickzanardo): This will not be needed anymore when // this issue is merged: https://github.com/flame-engine/flame/issues/1513 -class WrappedGameController extends GameController { - WrappedGameController(this._gameRef); +class WrappedGameFlowController extends GameFlowController { + WrappedGameFlowController(this._gameRef); final PinballGame _gameRef; @@ -20,7 +20,7 @@ class WrappedGameController extends GameController { } void main() { - group('GameController', () { + group('GameFlowController', () { group('listenWhen', () { test('is true when the game over state has changed', () { final state = GameState( @@ -33,7 +33,7 @@ void main() { final previous = GameState.initial(); expect( - GameController().listenWhen(previous, state), + GameFlowController().listenWhen(previous, state), isTrue, ); }); @@ -43,14 +43,14 @@ void main() { late PinballGame game; late Backboard backboard; late CameraController cameraController; - late GameController gameController; + late GameFlowController gameFlowController; late ActiveOverlaysNotifier overlays; setUp(() { game = MockPinballGame(); backboard = MockBackboard(); cameraController = MockCameraController(); - gameController = WrappedGameController(game); + gameFlowController = WrappedGameFlowController(game); overlays = MockActiveOverlaysNotifier(); when(backboard.gameOverMode).thenAnswer((_) async {}); @@ -68,7 +68,7 @@ void main() { test( 'changes the backboard and camera correctly when it is a game over', () { - gameController.onNewState( + gameFlowController.onNewState( GameState( score: 10, balls: 0, @@ -86,7 +86,7 @@ void main() { test( 'changes the backboard and camera correctly when it is not a game over', () { - gameController.onNewState(GameState.initial()); + gameFlowController.onNewState(GameState.initial()); verify(backboard.waitingMode).called(1); verify(cameraController.focusOnGame).called(1); diff --git a/test/game/view/play_button_overlay_test.dart b/test/game/view/play_button_overlay_test.dart index f07e4dc8..020998d4 100644 --- a/test/game/view/play_button_overlay_test.dart +++ b/test/game/view/play_button_overlay_test.dart @@ -7,14 +7,14 @@ import '../../helpers/helpers.dart'; void main() { group('PlayButtonOverlay', () { late PinballGame game; - late GameController gameController; + late GameFlowController gameFlowController; setUp(() { game = MockPinballGame(); - gameController = MockGameController(); + gameFlowController = MockGameFlowController(); - when(() => game.gameController).thenReturn(gameController); - when(gameController.start).thenAnswer((_) {}); + when(() => game.gameFlowController).thenReturn(gameFlowController); + when(gameFlowController.start).thenAnswer((_) {}); }); testWidgets('renders correctly', (tester) async { @@ -23,13 +23,13 @@ void main() { expect(find.text('Play'), findsOneWidget); }); - testWidgets('calls gameController.start when taped', (tester) async { + testWidgets('calls gameFlowController.start when taped', (tester) async { await tester.pumpApp(PlayButtonOverlay(game: game)); await tester.tap(find.text('Play')); await tester.pump(); - verify(gameController.start).called(1); + verify(gameFlowController.start).called(1); }); }); } diff --git a/test/helpers/mocks.dart b/test/helpers/mocks.dart index 3d63ba8e..941da872 100644 --- a/test/helpers/mocks.dart +++ b/test/helpers/mocks.dart @@ -85,4 +85,4 @@ class MockCameraController extends Mock implements CameraController {} class MockActiveOverlaysNotifier extends Mock implements ActiveOverlaysNotifier {} -class MockGameController extends Mock implements GameController {} +class MockGameFlowController extends Mock implements GameFlowController {}