fix: handle game resizing (#446)

* fix: handle game resizing

* Update lib/game/behaviors/camera_focusing_behavior.dart

Co-authored-by: Erick <erickzanardoo@gmail.com>

Co-authored-by: Erick <erickzanardoo@gmail.com>
Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com>
pull/451/head
Jochum van der Ploeg 2 years ago committed by GitHub
parent 5e8ac20d37
commit 98ac639493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
@ -7,9 +9,9 @@ import 'package:pinball_components/pinball_components.dart';
/// {@template focus_data} /// {@template focus_data}
/// Defines a [Camera] focus point. /// Defines a [Camera] focus point.
/// {@endtemplate} /// {@endtemplate}
class FocusData { class _FocusData {
/// {@template focus_data} /// {@macro focus_data}
FocusData({ const _FocusData({
required this.zoom, required this.zoom,
required this.position, required this.position,
}); });
@ -24,7 +26,11 @@ class FocusData {
/// Changes the game focus when the [GameBloc] status changes. /// Changes the game focus when the [GameBloc] status changes.
class CameraFocusingBehavior extends Component class CameraFocusingBehavior extends Component
with FlameBlocListenable<GameBloc, GameState>, HasGameRef { with FlameBlocListenable<GameBloc, GameState>, HasGameRef {
late final Map<String, FocusData> _foci; final Map<GameStatus, _FocusData> _foci = {};
GameStatus? _activeFocus;
final _previousSize = Vector2.zero();
@override @override
bool listenWhen(GameState? previousState, GameState newState) { bool listenWhen(GameState? previousState, GameState newState) {
@ -32,51 +38,62 @@ class CameraFocusingBehavior extends Component
} }
@override @override
void onNewState(GameState state) { void onNewState(GameState state) => _zoomTo(state.status);
switch (state.status) {
case GameStatus.waiting:
break;
case GameStatus.playing:
_zoom(_foci['game']!);
break;
case GameStatus.gameOver:
_zoom(_foci['backbox']!);
break;
}
}
@override @override
Future<void> onLoad() async { void onGameResize(Vector2 size) {
await super.onLoad(); super.onGameResize(size);
_foci = { if (size == _previousSize) {
'game': FocusData( return;
zoom: gameRef.size.y / 16, }
position: Vector2(0, -7.8), _previousSize.setFrom(size);
),
'waiting': FocusData( final maxWidth = size.x / 90;
zoom: gameRef.size.y / 18, final maxHeight = size.y / 160;
final scale = min(maxHeight, maxWidth);
_foci.addAll({
GameStatus.waiting: _FocusData(
zoom: scale + (maxWidth > maxHeight ? 0.3 : -0.5),
position: Vector2(0, -112), position: Vector2(0, -112),
), ),
'backbox': FocusData( GameStatus.playing: _FocusData(
zoom: gameRef.size.y / 10, zoom: scale + (maxWidth > maxHeight ? 0.5 : -0.2),
position: Vector2(0, -7.8),
),
GameStatus.gameOver: _FocusData(
zoom: scale + (maxWidth > maxHeight ? 2.8 : 3.3),
position: Vector2(0, -111), position: Vector2(0, -111),
), ),
}; });
if (_activeFocus != null) {
_snap(_activeFocus!);
}
}
_snap(_foci['waiting']!); @override
Future<void> onLoad() async {
await super.onLoad();
_snap(GameStatus.waiting);
} }
void _snap(FocusData data) { void _snap(GameStatus focusKey) {
final focusData = _foci[_activeFocus = focusKey]!;
gameRef.camera gameRef.camera
..speed = 100 ..speed = 100
..followVector2(data.position) ..followVector2(focusData.position)
..zoom = data.zoom; ..zoom = focusData.zoom;
} }
void _zoom(FocusData data) { void _zoomTo(GameStatus focusKey) {
final zoom = CameraZoom(value: data.zoom); final focusData = _foci[_activeFocus = focusKey]!;
final zoom = CameraZoom(value: focusData.zoom);
zoom.completed.then((_) { zoom.completed.then((_) {
gameRef.camera.moveTo(data.position); gameRef.camera.moveTo(focusData.position);
}); });
add(zoom); add(zoom);
} }

@ -53,6 +53,20 @@ void main() {
}, },
); );
flameTester.test('sets zoom on resize', (game) async {
final behavior = CameraFocusingBehavior();
await game.ensureAdd(
FlameBlocProvider<GameBloc, GameState>.value(
value: GameBloc(),
children: [behavior],
),
);
game.onGameResize(game.canvasSize * 2);
expect(game.camera.zoom, equals(6.55));
});
flameTester.test( flameTester.test(
'listenWhen only listens when status changes', 'listenWhen only listens when status changes',
(game) async { (game) async {

Loading…
Cancel
Save