From 712b55f04b9922f05055621fef3b9efa8d55fb1f Mon Sep 17 00:00:00 2001 From: alestiago Date: Thu, 24 Mar 2022 12:56:42 +0000 Subject: [PATCH] feat: implemented DashNestBumper --- lib/game/components/board.dart | 45 +--------- lib/game/components/dash_nest_bumper.dart | 105 ++++++++++++++++++---- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart index d3e2617d..8254a1f2 100644 --- a/lib/game/components/board.dart +++ b/lib/game/components/board.dart @@ -1,9 +1,9 @@ import 'package:flame/components.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball/flame/blueprint.dart'; /// {@template board} -/// The main flat surface of the [PinballGame], where the [Flipper]s, -/// [DashNestBumper]s, [Kicker]s are arranged. +/// The main flat surface of the [PinballGame]. /// {entemplate} class Board extends Component { /// {@macro board} @@ -20,7 +20,7 @@ class Board extends Component { spacing: 2, ); - final dashForest = _FlutterForest( + final flutterForest = FlutterForest( position: Vector2( PinballGame.boardBounds.center.dx + 20, PinballGame.boardBounds.center.dy + 48, @@ -29,44 +29,7 @@ class Board extends Component { await addAll([ bottomGroup, - dashForest, - ]); - } -} - -/// {@template flutter_forest} -/// Area positioned at the top right of the [Board] where the [Ball] -/// can bounce off [DashNestBumper]s. -/// {@endtemplate} -class _FlutterForest extends Component { - /// {@macro flutter_forest} - _FlutterForest({ - required this.position, - }); - - final Vector2 position; - - @override - Future onLoad() async { - // TODO(alestiago): adjust positioning once sprites are added. - // TODO(alestiago): Use [NestBumper] instead of [RoundBumper] once provided. - final smallLeftNest = DashNestBumper( - radius: 1, - points: 10, - )..initialPosition = position + Vector2(-4.8, 2.8); - final smallRightNest = DashNestBumper( - radius: 1, - points: 10, - )..initialPosition = position + Vector2(0.5, -5.5); - final bigNest = DashNestBumper( - radius: 2, - points: 20, - )..initialPosition = position; - - await addAll([ - smallLeftNest, - smallRightNest, - bigNest, + flutterForest, ]); } } diff --git a/lib/game/components/dash_nest_bumper.dart b/lib/game/components/dash_nest_bumper.dart index da3504ff..fb5672ef 100644 --- a/lib/game/components/dash_nest_bumper.dart +++ b/lib/game/components/dash_nest_bumper.dart @@ -1,32 +1,105 @@ +// ignore_for_file: avoid_renaming_method_parameters + +import 'package:flame/components.dart'; +import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/game.dart'; +/// {@template flutter_forest} +/// Area positioned at the top right of the [Board] where the [Ball] +/// can bounce off [_DashNestBumper]s. +/// +/// When all [_DashNestBumper]s are hit at least once, the [GameBonus.dashNest] +/// is awarded, and the [_BigDashNestBumper] releases a new [Ball]. +/// {@endtemplate} +// TODO(alestiago): Make a [Blueprint] once nesting [Blueprint] is implemented. +class FlutterForest extends Component with HasGameRef { + /// {@macro flutter_forest} + FlutterForest({ + required this.position, + }); + + /// The position of the [FlutterForest] on the [Board]. + final Vector2 position; + + @override + Future onLoad() async { + gameRef.addContactCallback(_DashNestBumperBallContactCallback()); + + // TODO(alestiago): adjust positioning once sprites are added. + final smallLeftNest = _SmallDashNestBumper(id: 'small_left_nest') + ..initialPosition = position + Vector2(-4.8, 2.8); + final smallRightNest = _SmallDashNestBumper(id: 'small_right_nest') + ..initialPosition = position + Vector2(0.5, -5.5); + final bigNest = _BigDashNestBumper(id: 'big_nest') + ..initialPosition = position; + + await addAll([ + smallLeftNest, + smallRightNest, + bigNest, + ]); + } +} + /// {@template dash_nest_bumper} -/// Circular body that repels a [Ball] on contact, increasing the score. +/// Body that repels a [Ball] on contact. +/// +/// When hit, the [GameState.score] is increased. /// {@endtemplate} -class DashNestBumper extends BodyComponent with ScorePoints, InitialPosition { - /// {@macro dash_nest_bumper} - DashNestBumper({ - required double radius, - required int points, - }) : _radius = radius, - _points = points; +abstract class _DashNestBumper extends BodyComponent + with BlocComponent, ScorePoints, InitialPosition { + /// {@template dash_nest_bumper} + _DashNestBumper({required this.id}); + + final String id; +} + +class _DashNestBumperBallContactCallback + extends ContactCallback<_DashNestBumper, Ball> { + @override + void begin(_DashNestBumper dashNestBumper, Ball ball, Contact _) { + dashNestBumper.gameRef.read().add( + DashNestActivated(dashNestBumper.id), + ); + } +} + +class _BigDashNestBumper extends _DashNestBumper { + _BigDashNestBumper({required String id}) : super(id: id); - /// The radius of the [DashNestBumper]. - final double _radius; + @override + int get points => 20; + + @override + Body createBody() { + final shape = CircleShape()..radius = 2.5; + final fixtureDef = FixtureDef(shape); + + final bodyDef = BodyDef() + ..position = initialPosition + ..userData = this + ..type = BodyType.static; + + return world.createBody(bodyDef)..createFixture(fixtureDef); + } +} - /// Points awarded from hitting this [DashNestBumper]. - final int _points; +class _SmallDashNestBumper extends _DashNestBumper { + _SmallDashNestBumper({required String id}) : super(id: id); @override - int get points => _points; + int get points => 10; @override Body createBody() { - final shape = CircleShape()..radius = _radius; - final fixtureDef = FixtureDef(shape)..restitution = 1; + final shape = CircleShape()..radius = 1; + final fixtureDef = FixtureDef(shape); - final bodyDef = BodyDef()..position = initialPosition; + final bodyDef = BodyDef() + ..position = initialPosition + ..userData = this + ..type = BodyType.static; return world.createBody(bodyDef)..createFixture(fixtureDef); }