chore: remove wall and board

pull/224/head
Allison Ryan 3 years ago
parent 8a9c269b60
commit 398c543ec0

@ -2,47 +2,15 @@ import 'package:flame/components.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
/// {@template board}
/// The main flat surface of the [PinballGame].
/// {endtemplate}
class Board extends Component {
/// {@macro board}
// TODO(alestiago): Make Board a Blueprint and sort out priorities.
Board() : super(priority: 1);
@override
Future<void> onLoad() async {
// TODO(allisonryan0002): add bottom group and flutter forest to pinball
// game directly. Then remove board.
final bottomGroup = _BottomGroup();
final flutterForest = FlutterForest();
// TODO(alestiago): adjust positioning to real design.
// TODO(alestiago): add dino in pinball game.
final dino = ChromeDino()
..initialPosition = Vector2(
BoardDimensions.bounds.center.dx + 25,
BoardDimensions.bounds.center.dy - 10,
);
await addAll([
bottomGroup,
dino,
flutterForest,
]);
}
}
/// {@template bottom_group} /// {@template bottom_group}
/// Grouping of the board's bottom [Component]s. /// Grouping of the board's symmetrical bottom [Component]s.
/// ///
/// The [_BottomGroup] consists of[Flipper]s, [Baseboard]s and [Kicker]s. /// The [BottomGroup] consists of [Flipper]s, [Baseboard]s and [Kicker]s.
/// {@endtemplate} /// {@endtemplate}
// TODO(alestiago): Consider renaming once entire Board is defined. // TODO(allisonryan0002): Consider renaming.
class _BottomGroup extends Component { class BottomGroup extends Component {
/// {@macro bottom_group} /// {@macro bottom_group}
_BottomGroup() : super(priority: RenderPriority.bottomGroup); BottomGroup() : super(priority: RenderPriority.bottomGroup);
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
@ -58,7 +26,7 @@ class _BottomGroup extends Component {
} }
/// {@template bottom_group_side} /// {@template bottom_group_side}
/// Group with one side of [_BottomGroup]'s symmetric [Component]s. /// Group with one side of [BottomGroup]'s symmetric [Component]s.
/// ///
/// For example, [Flipper]s are symmetric components. /// For example, [Flipper]s are symmetric components.
/// {@endtemplate} /// {@endtemplate}

@ -1,14 +1,14 @@
export 'alien_zone.dart'; export 'alien_zone.dart';
export 'board.dart'; export 'bottom_group.dart';
export 'camera_controller.dart'; export 'camera_controller.dart';
export 'controlled_ball.dart'; export 'controlled_ball.dart';
export 'controlled_flipper.dart'; export 'controlled_flipper.dart';
export 'controlled_plunger.dart'; export 'controlled_plunger.dart';
export 'controlled_sparky_computer.dart'; export 'controlled_sparky_computer.dart';
export 'dino_desert.dart';
export 'flutter_forest.dart'; export 'flutter_forest.dart';
export 'game_flow_controller.dart'; export 'game_flow_controller.dart';
export 'google_word.dart'; export 'google_word.dart';
export 'launcher.dart'; export 'launcher.dart';
export 'score_points.dart'; export 'score_points.dart';
export 'sparky_fire_zone.dart'; export 'sparky_fire_zone.dart';
export 'wall.dart';

@ -1,4 +1,7 @@
// ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_forge2d/contact_callbacks.dart';
import 'package:flame_forge2d/forge2d_game.dart'; import 'package:flame_forge2d/forge2d_game.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
@ -51,8 +54,8 @@ class BallController extends ComponentController<Ball>
/// Removes the [Ball] from a [PinballGame]. /// Removes the [Ball] from a [PinballGame].
/// ///
/// Triggered by [BottomWallBallContactCallback] when the [Ball] falls into /// Triggered by [DrainBallContactCallback] when the [Ball] falls into
/// a [BottomWall]. /// a [Drain].
void lost() { void lost() {
component.shouldRemove = true; component.shouldRemove = true;
} }
@ -85,3 +88,13 @@ class DebugBallController extends BallController {
@override @override
void onRemove() {} void onRemove() {}
} }
/// {@template drain_ball_contact_callback}
/// Listens when a [ControlledBall] falls into a [Drain].
/// {@endtemplate}
class DrainBallContactCallback extends ContactCallback<ControlledBall, Drain> {
@override
void begin(ControlledBall ball, _, __) {
ball.controller.lost();
}
}

@ -0,0 +1,25 @@
import 'package:flame/components.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template dino_desert}
/// Area located next to the [Launcher] containing the [ChromeDino] and
/// [DinoWalls].
/// {@endtemplate}
// TODO(allisonryan0002): use a controller to initiate dino bonus when dino is
// fully implemented.
class DinoDesert extends Blueprint {
/// {@macro dino_desert}
DinoDesert()
: super(
components: [
ChromeDino()
..initialPosition = Vector2(
BoardDimensions.bounds.center.dx + 25,
BoardDimensions.bounds.center.dy - 10,
),
],
blueprints: [DinoWalls()],
);
}

@ -1,66 +0,0 @@
// ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/extensions.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets;
/// {@template wall}
/// A continuous generic and [BodyType.static] barrier that divides a game area.
/// {@endtemplate}
// TODO(alestiago): Remove [Wall] for [Pathway.straight].
class Wall extends BodyComponent {
/// {@macro wall}
Wall({
required this.start,
required this.end,
});
/// The [start] of the [Wall].
final Vector2 start;
/// The [end] of the [Wall].
final Vector2 end;
@override
Body createBody() {
final shape = EdgeShape()..set(start, end);
final fixtureDef = FixtureDef(shape)
..restitution = 0.1
..friction = 0;
final bodyDef = BodyDef()
..userData = this
..position = Vector2.zero()
..type = BodyType.static;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}
/// {@template bottom_wall}
/// [Wall] located at the bottom of the board.
///
/// Collisions with [BottomWall] are listened by
/// [BottomWallBallContactCallback].
/// {@endtemplate}
class BottomWall extends Wall {
/// {@macro bottom_wall}
BottomWall()
: super(
start: BoardDimensions.bounds.bottomLeft.toVector2(),
end: BoardDimensions.bounds.bottomRight.toVector2(),
);
}
/// {@template bottom_wall_ball_contact_callback}
/// Listens when a [ControlledBall] falls into a [BottomWall].
/// {@endtemplate}
class BottomWallBallContactCallback
extends ContactCallback<ControlledBall, BottomWall> {
@override
void begin(ControlledBall ball, BottomWall wall, Contact contact) {
ball.controller.lost();
}
}

@ -45,19 +45,18 @@ class PinballGame extends Forge2DGame
unawaited(add(gameFlowController = GameFlowController(this))); unawaited(add(gameFlowController = GameFlowController(this)));
unawaited(add(CameraController(this))); unawaited(add(CameraController(this)));
unawaited(add(Backboard.waiting(position: Vector2(0, -88)))); unawaited(add(Backboard.waiting(position: Vector2(0, -88))));
await add(Drain());
// TODO(allisonryan0002): banish Wall and Board classes in later PR. await add(BottomGroup());
await add(BottomWall());
unawaited(addFromBlueprint(Boundaries())); unawaited(addFromBlueprint(Boundaries()));
unawaited(addFromBlueprint(ControlledSparkyComputer())); unawaited(addFromBlueprint(ControlledSparkyComputer()));
final launcher = Launcher(); final launcher = Launcher();
unawaited(addFromBlueprint(launcher)); unawaited(addFromBlueprint(launcher));
unawaited(add(Board())); await add(FlutterForest());
unawaited(add(AlienZone())); unawaited(add(AlienZone()));
unawaited(add(SparkyFireZone())); unawaited(add(SparkyFireZone()));
unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(Slingshots()));
unawaited(addFromBlueprint(DinoWalls())); await addFromBlueprint(DinoDesert());
unawaited(_addBonusWord()); unawaited(_addBonusWord());
unawaited(addFromBlueprint(SpaceshipRamp())); unawaited(addFromBlueprint(SpaceshipRamp()));
unawaited( unawaited(
@ -75,7 +74,7 @@ class PinballGame extends Forge2DGame
void _addContactCallbacks() { void _addContactCallbacks() {
addContactCallback(BallScorePointsCallback(this)); addContactCallback(BallScorePointsCallback(this));
addContactCallback(BottomWallBallContactCallback()); addContactCallback(DrainBallContactCallback());
} }
Future<void> _addBonusWord() async { Future<void> _addBonusWord() async {

@ -10,6 +10,7 @@ export 'chrome_dino.dart';
export 'dash_animatronic.dart'; export 'dash_animatronic.dart';
export 'dash_nest_bumper.dart'; export 'dash_nest_bumper.dart';
export 'dino_walls.dart'; export 'dino_walls.dart';
export 'drain.dart';
export 'fire_effect.dart'; export 'fire_effect.dart';
export 'flipper.dart'; export 'flipper.dart';
export 'google_letter.dart'; export 'google_letter.dart';

@ -0,0 +1,26 @@
import 'package:flame/extensions.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template drain}
/// Area located at the bottom of the board to detect when a [Ball] is lost.
/// {@endtemplate}
class Drain extends BodyComponent {
/// {@macro drain}
Drain() {
renderBody = false;
}
@override
Body createBody() {
final start = BoardDimensions.bounds.bottomLeft.toVector2();
final end = BoardDimensions.bounds.bottomRight.toVector2();
final shape = EdgeShape()..set(start, end);
final fixtureDef = FixtureDef(shape, isSensor: true);
final bodyDef = BodyDef(userData: this);
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}

@ -0,0 +1,45 @@
// ignore_for_file: cascade_invocations
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(TestGame.new);
group('Drain', () {
flameTester.test(
'loads correctly',
(game) async {
final drain = Drain();
await game.ensureAdd(drain);
expect(game.contains(drain), isTrue);
},
);
flameTester.test(
'body is static',
(game) async {
final drain = Drain();
await game.ensureAdd(drain);
expect(drain.body.bodyType, equals(BodyType.static));
},
);
flameTester.test(
'is sensor',
(game) async {
final drain = Drain();
await game.ensureAdd(drain);
expect(drain.body.fixtures.first.isSensor, isTrue);
},
);
});
}

@ -1,120 +0,0 @@
// ignore_for_file: cascade_invocations
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.dash.bumper.main.active.keyName,
Assets.images.dash.bumper.main.inactive.keyName,
Assets.images.dash.bumper.a.active.keyName,
Assets.images.dash.bumper.a.inactive.keyName,
Assets.images.dash.bumper.b.active.keyName,
Assets.images.dash.bumper.b.inactive.keyName,
Assets.images.dash.animatronic.keyName,
Assets.images.signpost.inactive.keyName,
Assets.images.signpost.active1.keyName,
Assets.images.signpost.active2.keyName,
Assets.images.signpost.active3.keyName,
Assets.images.baseboard.left.keyName,
Assets.images.baseboard.right.keyName,
Assets.images.flipper.left.keyName,
Assets.images.flipper.right.keyName,
];
final flameTester = FlameTester(() => EmptyPinballTestGame(assets));
group('Board', () {
flameTester.test(
'loads correctly',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
expect(game.contains(board), isTrue);
},
);
group('loads', () {
flameTester.test(
'one left flipper',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final leftFlippers = board.descendants().whereType<Flipper>().where(
(flipper) => flipper.side.isLeft,
);
expect(leftFlippers.length, equals(1));
},
);
flameTester.test(
'one right flipper',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final rightFlippers = board.descendants().whereType<Flipper>().where(
(flipper) => flipper.side.isRight,
);
expect(rightFlippers.length, equals(1));
},
);
flameTester.test(
'two Baseboards',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final baseboards = board.descendants().whereType<Baseboard>();
expect(baseboards.length, equals(2));
},
);
flameTester.test(
'two Kickers',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final kickers = board.descendants().whereType<Kicker>();
expect(kickers.length, equals(2));
},
);
flameTester.test(
'one FlutterForest',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final flutterForest = board.descendants().whereType<FlutterForest>();
expect(flutterForest.length, equals(1));
},
);
flameTester.test(
'one ChromeDino',
(game) async {
final board = Board();
await game.ready();
await game.ensureAdd(board);
final chromeDino = board.descendants().whereType<ChromeDino>();
expect(chromeDino.length, equals(1));
},
);
});
});
}

@ -0,0 +1,88 @@
// ignore_for_file: cascade_invocations
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.baseboard.left.keyName,
Assets.images.baseboard.right.keyName,
Assets.images.flipper.left.keyName,
Assets.images.flipper.right.keyName,
];
final flameTester = FlameTester(() => EmptyPinballTestGame(assets));
group('BottomGroup', () {
flameTester.test(
'loads correctly',
(game) async {
final boattomGroup = BottomGroup();
await game.ready();
await game.ensureAdd(boattomGroup);
expect(game.contains(boattomGroup), isTrue);
},
);
group('loads', () {
flameTester.test(
'one left flipper',
(game) async {
final boattomGroup = BottomGroup();
await game.ready();
await game.ensureAdd(boattomGroup);
final leftFlippers =
boattomGroup.descendants().whereType<Flipper>().where(
(flipper) => flipper.side.isLeft,
);
expect(leftFlippers.length, equals(1));
},
);
flameTester.test(
'one right flipper',
(game) async {
final boattomGroup = BottomGroup();
await game.ready();
await game.ensureAdd(boattomGroup);
final rightFlippers =
boattomGroup.descendants().whereType<Flipper>().where(
(flipper) => flipper.side.isRight,
);
expect(rightFlippers.length, equals(1));
},
);
flameTester.test(
'two Baseboards',
(game) async {
final boattomGroup = BottomGroup();
await game.ready();
await game.ensureAdd(boattomGroup);
final baseboattomGroups =
boattomGroup.descendants().whereType<Baseboard>();
expect(baseboattomGroups.length, equals(2));
},
);
flameTester.test(
'two Kickers',
(game) async {
final boattomGroup = BottomGroup();
await game.ready();
await game.ensureAdd(boattomGroup);
final kickers = boattomGroup.descendants().whereType<Kicker>();
expect(kickers.length, equals(2));
},
);
});
});
}

@ -66,6 +66,21 @@ void main() {
}, },
); );
flameBlocTester.testGameWidget(
'DrainBallContactCallback calls lost',
setUp: (game, tester) async {
final contactCallback = DrainBallContactCallback();
final ball = MockControlledBall();
final drain = MockDrain();
final controller = MockBallController();
when(() => ball.controller).thenReturn(controller);
contactCallback.begin(ball, drain, MockContact());
verify(() => ball.controller.lost()).called(1);
},
);
group('turboCharge', () { group('turboCharge', () {
setUpAll(() { setUpAll(() {
registerFallbackValue(Vector2.zero()); registerFallbackValue(Vector2.zero());

@ -1,164 +0,0 @@
// ignore_for_file: cascade_invocations
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/game.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(EmptyPinballTestGame.new);
group('Wall', () {
flameTester.test(
'loads correctly',
(game) async {
await game.ready();
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
expect(game.contains(wall), isTrue);
},
);
group('body', () {
flameTester.test(
'positions correctly',
(game) async {
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
game.contains(wall);
expect(wall.body.position, Vector2.zero());
},
);
flameTester.test(
'is static',
(game) async {
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
expect(wall.body.bodyType, equals(BodyType.static));
},
);
});
group('fixture', () {
flameTester.test(
'exists',
(game) async {
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
expect(wall.body.fixtures[0], isA<Fixture>());
},
);
flameTester.test(
'has restitution',
(game) async {
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
final fixture = wall.body.fixtures[0];
expect(fixture.restitution, greaterThan(0));
},
);
flameTester.test(
'has no friction',
(game) async {
final wall = Wall(
start: Vector2.zero(),
end: Vector2(100, 0),
);
await game.ensureAdd(wall);
final fixture = wall.body.fixtures[0];
expect(fixture.friction, equals(0));
},
);
});
});
group(
'BottomWall',
() {
group('removes ball on contact', () {
late GameBloc gameBloc;
setUp(() {
gameBloc = GameBloc();
});
final flameBlocTester = FlameBlocTester<PinballGame, GameBloc>(
gameBuilder: EmptyPinballTestGame.new,
blocBuilder: () => gameBloc,
);
flameBlocTester.testGameWidget(
'when ball is launch',
setUp: (game, tester) async {
final ball = ControlledBall.launch(theme: game.theme);
final wall = BottomWall();
await game.ensureAddAll([ball, wall]);
game.addContactCallback(BottomWallBallContactCallback());
beginContact(game, ball, wall);
await game.ready();
expect(game.contains(ball), isFalse);
},
);
flameBlocTester.testGameWidget(
'when ball is bonus',
setUp: (game, tester) async {
final ball = ControlledBall.bonus(theme: game.theme);
final wall = BottomWall();
await game.ensureAddAll([ball, wall]);
game.addContactCallback(BottomWallBallContactCallback());
beginContact(game, ball, wall);
await game.ready();
expect(game.contains(ball), isFalse);
},
);
flameTester.test(
'when ball is debug',
(game) async {
final ball = ControlledBall.debug();
final wall = BottomWall();
await game.ensureAddAll([ball, wall]);
game.addContactCallback(BottomWallBallContactCallback());
beginContact(game, ball, wall);
await game.ready();
expect(game.contains(ball), isFalse);
},
);
});
},
);
}

@ -62,12 +62,12 @@ void main() {
// https://github.com/flame-engine/flame/issues/1416 // https://github.com/flame-engine/flame/issues/1416
group('components', () { group('components', () {
flameTester.test( flameTester.test(
'has only one BottomWall', 'has only one Drain',
(game) async { (game) async {
await game.ready(); await game.ready();
expect( expect(
game.children.whereType<BottomWall>().length, game.children.whereType<Drain>().length,
equals(1), equals(1),
); );
}, },
@ -84,10 +84,10 @@ void main() {
}, },
); );
flameTester.test('has one Board', (game) async { flameTester.test('has one FlutterForest', (game) async {
await game.ready(); await game.ready();
expect( expect(
game.children.whereType<Board>().length, game.children.whereType<FlutterForest>().length,
equals(1), equals(1),
); );
}); });
@ -120,7 +120,6 @@ void main() {
final flameBlocTester = FlameBlocTester<PinballGame, GameBloc>( final flameBlocTester = FlameBlocTester<PinballGame, GameBloc>(
gameBuilder: EmptyPinballTestGame.new, gameBuilder: EmptyPinballTestGame.new,
blocBuilder: () => gameBloc, blocBuilder: () => gameBloc,
// assets: assets,
); );
flameBlocTester.testGameWidget( flameBlocTester.testGameWidget(

@ -14,9 +14,7 @@ import 'package:pinball_components/pinball_components.dart';
class MockPinballGame extends Mock implements PinballGame {} class MockPinballGame extends Mock implements PinballGame {}
class MockWall extends Mock implements Wall {} class MockDrain extends Mock implements Drain {}
class MockBottomWall extends Mock implements BottomWall {}
class MockBody extends Mock implements Body {} class MockBody extends Mock implements Body {}

Loading…
Cancel
Save