feat: implemented `ScorePoints` mixin and callback (#7)

* feat: implemented ScorePoints mixin

* refactor: renamed BallHasScoreCallback to BallScorePointsCallback

* feat: included test for end method

* chore: included TODO comment

* docs: included doc comments

* feat: set ScorePoints mixin on BodyComponent

* feat: rewrote test for mixin only extending BodyComponent

* feat: registered BallScorePointsCallback in PinballGame

* docs: improved BallScorePointsCallback doc comment

* docs: changed PR url to issue url

* refactor: fixed analyzer warnings

* refactor: used real class names instead of Mock class names

Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com>

Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com>
pull/8/head
Alejandro Santiago 2 years ago committed by GitHub
parent 18e1f950ad
commit afeaf4a058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,8 +1,11 @@
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/body_component.dart';
import 'package:flutter/material.dart';
import 'package:forge2d/forge2d.dart';
import 'package:pinball/game/game.dart';
class Ball extends BodyComponent {
class Ball extends BodyComponent<PinballGame>
with BlocComponent<GameBloc, GameState> {
Ball({
required Vector2 position,
}) : _position = position {

@ -1 +1,2 @@
export 'ball.dart';
export 'score_points.dart';

@ -0,0 +1,30 @@
// ignore_for_file: avoid_renaming_method_parameters
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
/// {@template score_points}
/// Specifies the amount of points received on [Ball] collision.
/// {@endtemplate}
mixin ScorePoints on BodyComponent {
/// {@macro score_points}
int get points;
}
/// Adds points to the score when a [Ball] collides with a [BodyComponent] that
/// implements [ScorePoints].
class BallScorePointsCallback extends ContactCallback<Ball, ScorePoints> {
@override
void begin(
Ball ball,
ScorePoints hasPoints,
Contact _,
) {
ball.gameRef.read<GameBloc>().add(Scored(points: hasPoints.points));
}
// TODO(alestiago): remove once this issue is closed.
// https://github.com/flame-engine/flame/issues/1414
@override
void end(Ball _, ScorePoints __, Contact ___) {}
}

@ -1,4 +1,10 @@
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/forge2d_game.dart';
import 'package:pinball/game/game.dart';
class PinballGame extends Forge2DGame with FlameBloc {}
class PinballGame extends Forge2DGame with FlameBloc {
@override
Future<void> onLoad() async {
addContactCallback(BallScorePointsCallback());
}
}

@ -0,0 +1,80 @@
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
class MockBall extends Mock implements Ball {}
class MockGameBloc extends Mock implements GameBloc {}
class MockPinballGame extends Mock implements PinballGame {}
class FakeContact extends Fake implements Contact {}
class FakeGameEvent extends Fake implements GameEvent {}
class FakeScorePoints extends BodyComponent with ScorePoints {
@override
Body createBody() {
throw UnimplementedError();
}
@override
int get points => 2;
}
void main() {
group('BallScorePointsCallback', () {
late PinballGame game;
late GameBloc bloc;
late Ball ball;
late FakeScorePoints fakeScorePoints;
setUp(() {
game = MockPinballGame();
bloc = MockGameBloc();
ball = MockBall();
fakeScorePoints = FakeScorePoints();
});
setUpAll(() {
registerFallbackValue(FakeGameEvent());
});
group('begin', () {
test(
'emits Scored event with points',
() {
when<PinballGame>(() => ball.gameRef).thenReturn(game);
when<GameBloc>(game.read).thenReturn(bloc);
BallScorePointsCallback().begin(
ball,
fakeScorePoints,
FakeContact(),
);
verify(
() => bloc.add(
Scored(points: fakeScorePoints.points),
),
).called(1);
},
);
});
group('end', () {
test("doesn't add events to GameBloc", () {
BallScorePointsCallback().end(
ball,
fakeScorePoints,
FakeContact(),
);
verifyNever(
() => bloc.add(any()),
);
});
});
});
}

@ -0,0 +1,9 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
group('PinballGame', () {
// TODO(alestiago): test if [PinballGame] registers
// [BallScorePointsCallback] once the following issue is resolved:
// https://github.com/flame-engine/flame/issues/1416
});
}
Loading…
Cancel
Save