mirror of https://github.com/flutter/pinball.git
parent
8a9c269b60
commit
398c543ec0
@ -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();
|
||||
}
|
||||
}
|
@ -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));
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
@ -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);
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
Loading…
Reference in new issue