feat: implemented GameBallsController

pull/151/head
alestiago 4 years ago
parent ee86c83907
commit bd714ee269

@ -1,5 +1,4 @@
import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/forge2d_game.dart';
import 'package:flutter/material.dart';
import 'package:pinball/flame/flame.dart';
@ -34,7 +33,7 @@ class ControlledBall extends Ball with Controls<BallController> {
/// [Ball] used in [DebugPinballGame].
ControlledBall.debug() : super(baseColor: const Color(0xFFFF0000)) {
controller = BonusBallController(this);
controller = _DebugBallController(this);
}
}
@ -51,7 +50,10 @@ abstract class BallController extends ComponentController<Ball> {
/// Triggered by [BottomWallBallContactCallback] when the [Ball] falls into
/// a [BottomWall].
/// {@endtemplate}
void lost();
@mustCallSuper
void lost() {
component.shouldRemove = true;
}
}
/// {@template bonus_ball_controller}
@ -59,24 +61,13 @@ abstract class BallController extends ComponentController<Ball> {
///
/// A [BonusBallController] doesn't change the [GameState.balls] count.
/// {@endtemplate}
class BonusBallController extends BallController
with HasGameRef<PinballGame>, BlocComponent<GameBloc, GameState> {
class BonusBallController extends BallController with HasGameRef<PinballGame> {
/// {@macro bonus_ball_controller}
BonusBallController(Ball<Forge2DGame> component) : super(component);
@override
bool listenWhen(GameState? previousState, GameState newState) {
return (previousState?.balls ?? 0) > newState.balls;
}
@override
void onNewState(GameState state) {
super.onNewState(state);
component.shouldRemove = true;
}
@override
void lost() {
super.lost();
gameRef.read<GameBloc>().add(const BonusBallLost());
}
}
@ -87,28 +78,21 @@ class BonusBallController extends BallController
/// A [LaunchedBallController] changes the [GameState.balls] count.
/// {@endtemplate}
class LaunchedBallController extends BallController
with HasGameRef<PinballGame>, BlocComponent<GameBloc, GameState> {
with HasGameRef<PinballGame> {
/// {@macro launched_ball_controller}
LaunchedBallController(Ball<Forge2DGame> ball) : super(ball);
@override
bool listenWhen(GameState? previousState, GameState newState) {
return (previousState?.balls ?? 0) > newState.balls;
}
@override
void onNewState(GameState state) {
super.onNewState(state);
component.shouldRemove = true;
if (state.balls > 0) gameRef.spawnBall();
}
/// Removes the [Ball] from a [PinballGame]; spawning a new [Ball] if
/// any are left.
///
/// {@macro ball_controller_lost}
@override
void lost() {
super.lost();
gameRef.read<GameBloc>().add(const BallLost());
}
}
class _DebugBallController extends BallController {
_DebugBallController(Ball<Forge2DGame> ball) : super(ball);
}

@ -6,6 +6,7 @@ import 'package:flame/extensions.dart';
import 'package:flame/input.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/flame/flame.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/gen/assets.gen.dart';
import 'package:pinball_audio/pinball_audio.dart';
@ -13,9 +14,16 @@ import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_theme/pinball_theme.dart' hide Assets;
class PinballGame extends Forge2DGame
with FlameBloc, HasKeyboardHandlerComponents {
PinballGame({required this.theme, required this.audio}) {
with
FlameBloc,
HasKeyboardHandlerComponents,
Controls<_GameBallsController> {
PinballGame({
required this.theme,
required this.audio,
}) {
images.prefix = '';
controller = _GameBallsController(this);
}
final PinballTheme theme;
@ -25,11 +33,12 @@ class PinballGame extends Forge2DGame
@override
void onAttach() {
super.onAttach();
spawnBall();
controller.spawnBall();
}
@override
Future<void> onLoad() async {
await super.onLoad();
_addContactCallbacks();
await _addGameBoundaries();
@ -87,6 +96,28 @@ class PinballGame extends Forge2DGame
),
);
}
}
class _GameBallsController extends ComponentController<PinballGame>
with BlocComponent<GameBloc, GameState>, HasGameRef<PinballGame> {
_GameBallsController(PinballGame game) : super(game);
@override
bool listenWhen(GameState? previousState, GameState newState) {
// TODO(alestiago): Fix how the logic works.
final previousBalls =
(previousState?.balls ?? 0) + (previousState?.bonusBalls ?? 0);
final currentBalls = newState.balls + newState.bonusBalls;
final canBallRespawn = newState.balls > 0 && newState.bonusBalls == 0;
return previousBalls != currentBalls && canBallRespawn;
}
@override
void onNewState(GameState state) {
super.onNewState(state);
spawnBall();
}
Future<void> spawnBall() async {
// TODO(alestiago): Remove once this logic is moved to controller.
@ -96,7 +127,7 @@ class PinballGame extends Forge2DGame
}
final ball = ControlledBall.launch(
theme: theme,
theme: gameRef.theme,
)..initialPosition = Vector2(
plunger.body.position.x,
plunger.body.position.y + Ball.size.y,

Loading…
Cancel
Save