Merge branch 'main' into feat/leaderboard_screen

pull/51/head
Rui Miguel Alonso 4 years ago committed by GitHub
commit e013ba8bd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

@ -14,6 +14,8 @@ const _attachedErrorMessage = "Can't add to attached Blueprints";
/// the [FlameGame] level. /// the [FlameGame] level.
abstract class Blueprint<T extends FlameGame> { abstract class Blueprint<T extends FlameGame> {
final List<Component> _components = []; final List<Component> _components = [];
final List<Blueprint> _blueprints = [];
bool _isAttached = false; bool _isAttached = false;
/// Called before the the [Component]s managed /// Called before the the [Component]s managed
@ -25,7 +27,10 @@ abstract class Blueprint<T extends FlameGame> {
@mustCallSuper @mustCallSuper
Future<void> attach(T game) async { Future<void> attach(T game) async {
build(game); build(game);
await game.addAll(_components); await Future.wait([
game.addAll(_components),
..._blueprints.map(game.addFromBlueprint).toList(),
]);
_isAttached = true; _isAttached = true;
} }
@ -41,8 +46,23 @@ abstract class Blueprint<T extends FlameGame> {
_components.add(component); _components.add(component);
} }
/// Adds a list of [Blueprint]s to this blueprint.
void addAllBlueprints(List<Blueprint> blueprints) {
assert(!_isAttached, _attachedErrorMessage);
_blueprints.addAll(blueprints);
}
/// Adds a single [Blueprint] to this blueprint.
void addBlueprint(Blueprint blueprint) {
assert(!_isAttached, _attachedErrorMessage);
_blueprints.add(blueprint);
}
/// Returns a copy of the components built by this blueprint /// Returns a copy of the components built by this blueprint
List<Component> get components => List.unmodifiable(_components); List<Component> get components => List.unmodifiable(_components);
/// Returns a copy of the children blueprints
List<Blueprint> get blueprints => List.unmodifiable(_blueprints);
} }
/// A [Blueprint] that provides additional /// A [Blueprint] that provides additional

@ -5,7 +5,7 @@ import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
/// {@template baseboard} /// {@template baseboard}
/// Straight, angled board piece to corral the [Ball] towards the [Flipper]s. /// Wing-shaped board piece to corral the [Ball] towards the [Flipper]s.
/// {@endtemplate} /// {@endtemplate}
class Baseboard extends BodyComponent with InitialPosition { class Baseboard extends BodyComponent with InitialPosition {
/// {@macro baseboard} /// {@macro baseboard}
@ -13,41 +13,68 @@ class Baseboard extends BodyComponent with InitialPosition {
required BoardSide side, required BoardSide side,
}) : _side = side; }) : _side = side;
/// The width of the [Baseboard]. /// The size of the [Baseboard].
static const width = 10.0; static final size = Vector2(24.2, 13.5);
/// The height of the [Baseboard].
static const height = 2.0;
/// Whether the [Baseboard] is on the left or right side of the board. /// Whether the [Baseboard] is on the left or right side of the board.
final BoardSide _side; final BoardSide _side;
List<FixtureDef> _createFixtureDefs() { List<FixtureDef> _createFixtureDefs() {
final fixturesDef = <FixtureDef>[]; final fixturesDef = <FixtureDef>[];
final direction = _side.direction;
final arcsAngle = -1.11 * direction;
const arcsRotation = math.pi / 2.08;
final topCircleShape = CircleShape()..radius = 0.7;
topCircleShape.position.setValues(11.39 * direction, 6.05);
final topCircleFixtureDef = FixtureDef(topCircleShape);
fixturesDef.add(topCircleFixtureDef);
final innerEdgeShape = EdgeShape()
..set(
Vector2(10.86 * direction, 6.45),
Vector2(6.96 * direction, 0.25),
);
final innerEdgeShapeFixtureDef = FixtureDef(innerEdgeShape);
fixturesDef.add(innerEdgeShapeFixtureDef);
final outerEdgeShape = EdgeShape()
..set(
Vector2(11.96 * direction, 5.85),
Vector2(5.48 * direction, -4.85),
);
final outerEdgeShapeFixtureDef = FixtureDef(outerEdgeShape);
fixturesDef.add(outerEdgeShapeFixtureDef);
final upperArcFixtureDefs = Pathway.arc(
center: Vector2(1.76 * direction, 3.25),
width: 0,
radius: 6.1,
angle: arcsAngle,
rotation: arcsRotation,
singleWall: true,
).createFixtureDefs();
fixturesDef.addAll(upperArcFixtureDefs);
final lowerArcFixtureDefs = Pathway.arc(
center: Vector2(1.85 * direction, -2.15),
width: 0,
radius: 4.5,
angle: arcsAngle,
rotation: arcsRotation,
singleWall: true,
).createFixtureDefs();
fixturesDef.addAll(lowerArcFixtureDefs);
final circleShape1 = CircleShape()..radius = Baseboard.height / 2; final bottomRectangle = PolygonShape()
circleShape1.position.setValues( ..setAsBox(
-(Baseboard.width / 2) + circleShape1.radius, 7,
0, 2,
); Vector2(-5.14 * direction, -4.75),
final circle1FixtureDef = FixtureDef(circleShape1); 0,
fixturesDef.add(circle1FixtureDef);
final circleShape2 = CircleShape()..radius = Baseboard.height / 2;
circleShape2.position.setValues(
(Baseboard.width / 2) - circleShape2.radius,
0,
);
final circle2FixtureDef = FixtureDef(circleShape2);
fixturesDef.add(circle2FixtureDef);
final rectangle = PolygonShape()
..setAsBoxXY(
(Baseboard.width - Baseboard.height) / 2,
Baseboard.height / 2,
); );
final rectangleFixtureDef = FixtureDef(rectangle); final bottomRectangleFixtureDef = FixtureDef(bottomRectangle);
fixturesDef.add(rectangleFixtureDef); fixturesDef.add(bottomRectangleFixtureDef);
return fixturesDef; return fixturesDef;
} }
@ -56,7 +83,7 @@ class Baseboard extends BodyComponent with InitialPosition {
Body createBody() { Body createBody() {
// TODO(allisonryan0002): share sweeping angle with flipper when components // TODO(allisonryan0002): share sweeping angle with flipper when components
// are grouped. // are grouped.
const angle = math.pi / 7; const angle = math.pi / 5;
final bodyDef = BodyDef() final bodyDef = BodyDef()
..position = initialPosition ..position = initialPosition

@ -1,11 +1,9 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template board} /// {@template board}
/// The main flat surface of the [PinballGame], where the [Flipper]s, /// The main flat surface of the [PinballGame].
/// [RoundBumper]s, [Kicker]s are arranged. /// {endtemplate}
/// {entemplate}
class Board extends Component { class Board extends Component {
/// {@macro board} /// {@macro board}
Board(); Board();
@ -21,7 +19,7 @@ class Board extends Component {
spacing: 2, spacing: 2,
); );
final dashForest = _FlutterForest( final flutterForest = FlutterForest(
position: Vector2( position: Vector2(
PinballGame.boardBounds.center.dx + 20, PinballGame.boardBounds.center.dx + 20,
PinballGame.boardBounds.center.dy + 48, PinballGame.boardBounds.center.dy + 48,
@ -30,44 +28,7 @@ class Board extends Component {
await addAll([ await addAll([
bottomGroup, bottomGroup,
dashForest, flutterForest,
]);
}
}
/// {@template flutter_forest}
/// Area positioned at the top right of the [Board] where the [Ball]
/// can bounce off [RoundBumper]s.
/// {@endtemplate}
class _FlutterForest extends Component {
/// {@macro flutter_forest}
_FlutterForest({
required this.position,
});
final Vector2 position;
@override
Future<void> onLoad() async {
// TODO(alestiago): adjust positioning once sprites are added.
// TODO(alestiago): Use [NestBumper] instead of [RoundBumper] once provided.
final smallLeftNest = RoundBumper(
radius: 1,
points: 10,
)..initialPosition = position + Vector2(-4.8, 2.8);
final smallRightNest = RoundBumper(
radius: 1,
points: 10,
)..initialPosition = position + Vector2(0.5, -5.5);
final bigNest = RoundBumper(
radius: 2,
points: 20,
)..initialPosition = position;
await addAll([
smallLeftNest,
smallRightNest,
bigNest,
]); ]);
} }
} }
@ -134,8 +95,8 @@ class _BottomGroupSide extends Component {
final baseboard = Baseboard(side: _side) final baseboard = Baseboard(side: _side)
..initialPosition = _position + ..initialPosition = _position +
Vector2( Vector2(
(Flipper.size.x * direction) - direction, (Baseboard.size.x / 1.6 * direction),
Flipper.size.y, Baseboard.size.y - 2,
); );
final kicker = Kicker( final kicker = Kicker(
side: _side, side: _side,

@ -21,13 +21,9 @@ class BonusWord extends Component with BlocComponent<GameBloc, GameState> {
@override @override
bool listenWhen(GameState? previousState, GameState newState) { bool listenWhen(GameState? previousState, GameState newState) {
if ((previousState?.bonusHistory.length ?? 0) < return (previousState?.bonusHistory.length ?? 0) <
newState.bonusHistory.length && newState.bonusHistory.length &&
newState.bonusHistory.last == GameBonus.word) { newState.bonusHistory.last == GameBonus.word;
return true;
}
return false;
} }
@override @override

@ -4,6 +4,7 @@ export 'board.dart';
export 'board_side.dart'; export 'board_side.dart';
export 'bonus_word.dart'; export 'bonus_word.dart';
export 'flipper.dart'; export 'flipper.dart';
export 'flutter_forest.dart';
export 'jetpack_ramp.dart'; export 'jetpack_ramp.dart';
export 'joint_anchor.dart'; export 'joint_anchor.dart';
export 'kicker.dart'; export 'kicker.dart';
@ -11,7 +12,6 @@ export 'launcher_ramp.dart';
export 'pathway.dart'; export 'pathway.dart';
export 'plunger.dart'; export 'plunger.dart';
export 'ramp_opening.dart'; export 'ramp_opening.dart';
export 'round_bumper.dart';
export 'score_points.dart'; export 'score_points.dart';
export 'spaceship.dart'; export 'spaceship.dart';
export 'wall.dart'; export 'wall.dart';

@ -0,0 +1,131 @@
// 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:flutter/material.dart';
import 'package:pinball/flame/blueprint.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.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<PinballGame>, BlocComponent<GameBloc, GameState> {
/// {@macro flutter_forest}
FlutterForest({
required this.position,
});
/// The position of the [FlutterForest] on the [Board].
final Vector2 position;
@override
bool listenWhen(GameState? previousState, GameState newState) {
return (previousState?.bonusHistory.length ?? 0) <
newState.bonusHistory.length &&
newState.bonusHistory.last == GameBonus.dashNest;
}
@override
void onNewState(GameState state) {
super.onNewState(state);
gameRef.addFromBlueprint(BallBlueprint(position: position));
}
@override
Future<void> 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}
/// Bumper located in the [FlutterForest].
/// {@endtemplate}
@visibleForTesting
abstract class DashNestBumper extends BodyComponent<PinballGame>
with ScorePoints, InitialPosition {
/// {@macro dash_nest_bumper}
DashNestBumper({required this.id});
/// Unique identifier for this [DashNestBumper].
///
/// Used to identify [DashNestBumper]s in [GameState.activatedDashNests].
final String id;
}
/// Listens when a [Ball] bounces bounces against a [DashNestBumper].
@visibleForTesting
class DashNestBumperBallContactCallback
extends ContactCallback<DashNestBumper, Ball> {
@override
void begin(DashNestBumper dashNestBumper, Ball ball, Contact _) {
dashNestBumper.gameRef.read<GameBloc>().add(
DashNestActivated(dashNestBumper.id),
);
}
}
/// {@macro dash_nest_bumper}
@visibleForTesting
class BigDashNestBumper extends DashNestBumper {
/// {@macro dash_nest_bumper}
BigDashNestBumper({required String id}) : super(id: id);
@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;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}
/// {@macro dash_nest_bumper}
@visibleForTesting
class SmallDashNestBumper extends DashNestBumper {
/// {@macro dash_nest_bumper}
SmallDashNestBumper({required String id}) : super(id: id);
@override
int get points => 10;
@override
Body createBody() {
final shape = CircleShape()..radius = 1;
final fixtureDef = FixtureDef(shape);
final bodyDef = BodyDef()
..position = initialPosition
..userData = this;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}

@ -1,35 +0,0 @@
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template round_bumper}
/// Circular body that repels a [Ball] on contact, increasing the score.
/// {@endtemplate}
class RoundBumper extends BodyComponent with ScorePoints, InitialPosition {
/// {@macro round_bumper}
RoundBumper({
required double radius,
required int points,
}) : _radius = radius,
_points = points;
/// The radius of the [RoundBumper].
final double _radius;
/// Points awarded from hitting this [RoundBumper].
final int _points;
@override
int get points => _points;
@override
Body createBody() {
final shape = CircleShape()..radius = _radius;
final fixtureDef = FixtureDef(shape)..restitution = 1;
final bodyDef = BodyDef()..position = initialPosition;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}

@ -17,8 +17,6 @@ class $AssetsImagesComponentsGen {
AssetGenImage get flipper => AssetGenImage get flipper =>
const AssetGenImage('assets/images/components/flipper.png'); const AssetGenImage('assets/images/components/flipper.png');
AssetGenImage get sauce =>
const AssetGenImage('assets/images/components/sauce.png');
$AssetsImagesComponentsSpaceshipGen get spaceship => $AssetsImagesComponentsSpaceshipGen get spaceship =>
const $AssetsImagesComponentsSpaceshipGen(); const $AssetsImagesComponentsSpaceshipGen();
} }

@ -14,6 +14,28 @@ class MyBlueprint extends Blueprint {
} }
} }
class MyOtherBlueprint extends Blueprint {
@override
void build(_) {
add(Component());
}
}
class YetMyOtherBlueprint extends Blueprint {
@override
void build(_) {
add(Component());
}
}
class MyComposedBlueprint extends Blueprint {
@override
void build(_) {
addBlueprint(MyBlueprint());
addAllBlueprints([MyOtherBlueprint(), YetMyOtherBlueprint()]);
}
}
class MyForge2dBlueprint extends Forge2DBlueprint { class MyForge2dBlueprint extends Forge2DBlueprint {
@override @override
void build(_) { void build(_) {
@ -24,12 +46,23 @@ class MyForge2dBlueprint extends Forge2DBlueprint {
void main() { void main() {
group('Blueprint', () { group('Blueprint', () {
setUpAll(() {
registerFallbackValue(MyBlueprint());
registerFallbackValue(Component());
});
test('components can be added to it', () { test('components can be added to it', () {
final blueprint = MyBlueprint()..build(MockPinballGame()); final blueprint = MyBlueprint()..build(MockPinballGame());
expect(blueprint.components.length, equals(3)); expect(blueprint.components.length, equals(3));
}); });
test('blueprints can be added to it', () {
final blueprint = MyComposedBlueprint()..build(MockPinballGame());
expect(blueprint.blueprints.length, equals(3));
});
test('adds the components to a game on attach', () { test('adds the components to a game on attach', () {
final mockGame = MockPinballGame(); final mockGame = MockPinballGame();
when(() => mockGame.addAll(any())).thenAnswer((_) async {}); when(() => mockGame.addAll(any())).thenAnswer((_) async {});
@ -38,6 +71,14 @@ void main() {
verify(() => mockGame.addAll(any())).called(1); verify(() => mockGame.addAll(any())).called(1);
}); });
test('adds components from a child Blueprint the to a game on attach', () {
final mockGame = MockPinballGame();
when(() => mockGame.addAll(any())).thenAnswer((_) async {});
MyComposedBlueprint().attach(mockGame);
verify(() => mockGame.addAll(any())).called(4);
});
test( test(
'throws assertion error when adding to an already attached blueprint', 'throws assertion error when adding to an already attached blueprint',
() async { () async {

@ -61,14 +61,14 @@ void main() {
group('fixtures', () { group('fixtures', () {
flameTester.test( flameTester.test(
'has three', 'has six',
(game) async { (game) async {
final baseboard = Baseboard( final baseboard = Baseboard(
side: BoardSide.left, side: BoardSide.left,
); );
await game.ensureAdd(baseboard); await game.ensureAdd(baseboard);
expect(baseboard.body.fixtures.length, equals(3)); expect(baseboard.body.fixtures.length, equals(6));
}, },
); );
}); });

@ -75,15 +75,15 @@ void main() {
); );
flameTester.test( flameTester.test(
'has three RoundBumpers', 'has one FlutterForest',
(game) async { (game) async {
// TODO(alestiago): change to [NestBumpers] once provided. // TODO(alestiago): change to [NestBumpers] once provided.
final board = Board(); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
final roundBumpers = board.descendants().whereType<RoundBumper>(); final flutterForest = board.descendants().whereType<FlutterForest>();
expect(roundBumpers.length, equals(3)); expect(flutterForest.length, equals(1));
}, },
); );
}); });

@ -194,6 +194,7 @@ void main() {
group('bonus letter activation', () { group('bonus letter activation', () {
final gameBloc = MockGameBloc(); final gameBloc = MockGameBloc();
final tester = flameBlocTester(gameBloc: () => gameBloc);
BonusLetter _getBonusLetter(PinballGame game) { BonusLetter _getBonusLetter(PinballGame game) {
return game.children return game.children
@ -212,8 +213,6 @@ void main() {
); );
}); });
final tester = flameBlocTester(gameBloc: () => gameBloc);
tester.widgetTest( tester.widgetTest(
'adds BonusLetterActivated to GameBloc when not activated', 'adds BonusLetterActivated to GameBloc when not activated',
(game, tester) async { (game, tester) async {

@ -0,0 +1,125 @@
// ignore_for_file: cascade_invocations
import 'package:bloc_test/bloc_test.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(PinballGameTest.create);
group('FlutterForest', () {
flameTester.test(
'loads correctly',
(game) async {
await game.ready();
final flutterForest = FlutterForest(position: Vector2(0, 0));
await game.ensureAdd(flutterForest);
expect(game.contains(flutterForest), isTrue);
},
);
flameTester.test(
'onNewState adds a new ball',
(game) async {
final flutterForest = FlutterForest(position: Vector2(0, 0));
await game.ready();
await game.ensureAdd(flutterForest);
final previousBalls = game.descendants().whereType<Ball>().length;
flutterForest.onNewState(MockGameState());
await game.ready();
expect(
game.descendants().whereType<Ball>().length,
greaterThan(previousBalls),
);
},
);
group('listenWhen', () {
final gameBloc = MockGameBloc();
final tester = flameBlocTester(gameBloc: () => gameBloc);
setUp(() {
whenListen(
gameBloc,
const Stream<GameState>.empty(),
initialState: const GameState.initial(),
);
});
tester.widgetTest(
'listens when a Bonus.dashNest is added',
(game, tester) async {
await game.ready();
final flutterForest =
game.descendants().whereType<FlutterForest>().first;
const state = GameState(
score: 0,
balls: 3,
activatedBonusLetters: [],
activatedDashNests: {},
bonusHistory: [GameBonus.dashNest],
);
expect(
flutterForest.listenWhen(const GameState.initial(), state),
isTrue,
);
},
);
});
});
group('DashNestBumperBallContactCallback', () {
final gameBloc = MockGameBloc();
final tester = flameBlocTester(gameBloc: () => gameBloc);
setUp(() {
whenListen(
gameBloc,
const Stream<GameState>.empty(),
initialState: const GameState.initial(),
);
});
tester.widgetTest(
'adds a DashNestActivated event with DashNestBumper.id',
(game, tester) async {
final contactCallback = DashNestBumperBallContactCallback();
const id = '0';
final dashNestBumper = MockDashNestBumper();
when(() => dashNestBumper.id).thenReturn(id);
when(() => dashNestBumper.gameRef).thenReturn(game);
contactCallback.begin(dashNestBumper, MockBall(), MockContact());
verify(() => gameBloc.add(DashNestActivated(dashNestBumper.id)))
.called(1);
},
);
});
group('BigDashNestBumper', () {
test('has points', () {
final dashNestBumper = BigDashNestBumper(id: '');
expect(dashNestBumper.points, greaterThan(0));
});
});
group('SmallDashNestBumper', () {
test('has points', () {
final dashNestBumper = SmallDashNestBumper(id: '');
expect(dashNestBumper.points, greaterThan(0));
});
});
}

@ -1,102 +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';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('RoundBumper', () {
final flameTester = FlameTester(Forge2DGame.new);
const radius = 1.0;
const points = 1;
flameTester.test(
'loads correctly',
(game) async {
await game.ready();
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
expect(game.contains(roundBumper), isTrue);
},
);
flameTester.test(
'has points',
(game) async {
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
expect(roundBumper.points, equals(points));
},
);
group('body', () {
flameTester.test(
'is static',
(game) async {
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
expect(roundBumper.body.bodyType, equals(BodyType.static));
},
);
});
group('fixture', () {
flameTester.test(
'exists',
(game) async {
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
expect(roundBumper.body.fixtures[0], isA<Fixture>());
},
);
flameTester.test(
'has restitution',
(game) async {
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
final fixture = roundBumper.body.fixtures[0];
expect(fixture.restitution, greaterThan(0));
},
);
flameTester.test(
'shape is circular',
(game) async {
final roundBumper = RoundBumper(
radius: radius,
points: points,
);
await game.ensureAdd(roundBumper);
final fixture = roundBumper.body.fixtures[0];
expect(fixture.shape.shapeType, equals(ShapeType.circle));
expect(fixture.shape.radius, equals(1));
},
);
});
});
}

@ -73,3 +73,5 @@ class MockSpaceshipEntrance extends Mock implements SpaceshipEntrance {}
class MockSpaceshipHole extends Mock implements SpaceshipHole {} class MockSpaceshipHole extends Mock implements SpaceshipHole {}
class MockComponentSet extends Mock implements ComponentSet {} class MockComponentSet extends Mock implements ComponentSet {}
class MockDashNestBumper extends Mock implements DashNestBumper {}

Loading…
Cancel
Save