feat: pr suggestions

pull/160/head
Erick Zanardo 4 years ago
parent e9d1819ec0
commit 338b26a50f

@ -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<void> 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<void> 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<void> 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));
}
}

@ -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';

@ -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<GameBloc, GameState>, HasGameRef {
@override
bool listenWhen(GameState? previousState, GameState newState) {

@ -32,13 +32,13 @@ class PinballGame extends Forge2DGame
final PinballAudio audio;
late final GameController gameController;
late final GameFlowController gameFlowController;
@override
Future<void> onLoad() async {
_addContactCallbacks();
unawaited(add(gameController = GameController()));
unawaited(add(gameFlowController = GameFlowController()));
unawaited(add(CameraController()));
unawaited(add(Backboard(position: Vector2(0, -88))));

@ -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),
),
);

@ -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<CameraZoom>();
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<CameraZoom>()!;
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<CameraZoom>();
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<CameraZoom>()!;
final future = cameraZoom.completed;
game.update(10);
game.update(0); // Ensure that the component was removed

@ -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);

@ -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);
});
});
}

@ -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 {}

Loading…
Cancel
Save