feat: add game boundaries (#131)

* feat: add outer and bottom boundaries

* test: add golden test

* refactor: load sprite method
pull/140/head
Allison Ryan 2 years ago committed by GitHub
parent ab1dbe99d5
commit b41cd80540
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -68,7 +68,7 @@ class _FlutterForestController extends ComponentController<FlutterForest>
void onNewState(GameState state) {
super.onNewState(state);
component.add(
gameRef.add(
ControlledBall.bonus(theme: gameRef.theme)
..initialPosition = Vector2(17.2, 52.7),
);

@ -27,6 +27,8 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.dashBumper.b.inactive.keyName),
images.load(components.Assets.images.dashBumper.main.active.keyName),
images.load(components.Assets.images.dashBumper.main.inactive.keyName),
images.load(components.Assets.images.boundary.bottom.keyName),
images.load(components.Assets.images.boundary.outer.keyName),
images.load(components.Assets.images.spaceshipRamp.spaceshipRamp.keyName),
images.load(
components.Assets.images.spaceshipRamp.spaceshipRailingBg.keyName,

@ -33,6 +33,7 @@ class PinballGame extends Forge2DGame
await _addGameBoundaries();
unawaited(add(Board()));
unawaited(addFromBlueprint(Boundaries()));
unawaited(_addPlunger());
unawaited(_addBonusWord());
unawaited(_addRamps());

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

@ -14,6 +14,7 @@ class $AssetsImagesGen {
AssetGenImage get ball => const AssetGenImage('assets/images/ball.png');
$AssetsImagesBaseboardGen get baseboard => const $AssetsImagesBaseboardGen();
$AssetsImagesBoundaryGen get boundary => const $AssetsImagesBoundaryGen();
$AssetsImagesChromeDinoGen get chromeDino =>
const $AssetsImagesChromeDinoGen();
$AssetsImagesDashBumperGen get dashBumper =>
@ -52,6 +53,18 @@ class $AssetsImagesBaseboardGen {
const AssetGenImage('assets/images/baseboard/right.png');
}
class $AssetsImagesBoundaryGen {
const $AssetsImagesBoundaryGen();
/// File path: assets/images/boundary/bottom.png
AssetGenImage get bottom =>
const AssetGenImage('assets/images/boundary/bottom.png');
/// File path: assets/images/boundary/outer.png
AssetGenImage get outer =>
const AssetGenImage('assets/images/boundary/outer.png');
}
class $AssetsImagesChromeDinoGen {
const $AssetsImagesChromeDinoGen();

@ -0,0 +1,156 @@
// ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template boundaries}
/// A [Blueprint] which creates the [_BottomBoundary] and [_OuterBoundary].
///{@endtemplate boundaries}
class Boundaries extends Forge2DBlueprint {
@override
void build(_) {
final bottomBoundary = _BottomBoundary();
final outerBoundary = _OuterBoundary();
addAll([bottomBoundary, outerBoundary]);
}
}
/// {@template bottom_boundary}
/// Curved boundary at the bottom of the board where the [Ball] exits the field
/// of play.
/// {@endtemplate bottom_boundary}
class _BottomBoundary extends BodyComponent with InitialPosition {
/// {@macro bottom_boundary}
_BottomBoundary() : super(priority: 2);
List<FixtureDef> _createFixtureDefs() {
final fixturesDefs = <FixtureDef>[];
final bottomLeftCurve = BezierCurveShape(
controlPoints: [
Vector2(-43.6, -44.4),
Vector2(-31, -43.4),
Vector2(-18.7, -52.1),
],
);
final bottomLeftCurveFixtureDef = FixtureDef(bottomLeftCurve);
fixturesDefs.add(bottomLeftCurveFixtureDef);
final bottomRightCurve = BezierCurveShape(
controlPoints: [
Vector2(31.8, -44.1),
Vector2(21.95, -47),
Vector2(12.3, -51.4),
],
);
final bottomRightCurveFixtureDef = FixtureDef(bottomRightCurve);
fixturesDefs.add(bottomRightCurveFixtureDef);
return fixturesDefs;
}
@override
Body createBody() {
final bodyDef = BodyDef()..position = initialPosition;
final body = world.createBody(bodyDef);
_createFixtureDefs().forEach(body.createFixture);
return body;
}
@override
Future<void> onLoad() async {
await super.onLoad();
await _loadSprite();
renderBody = false;
}
Future<void> _loadSprite() async {
final sprite = await gameRef.loadSprite(
Assets.images.boundary.bottom.keyName,
);
await add(
SpriteComponent(
sprite: sprite,
size: sprite.originalSize / 10,
anchor: Anchor.center,
position: Vector2(-5.4, 57.4),
),
);
}
}
/// {@template outer_boundary}
/// Boundary enclosing the top and left side of the board. The right side of the
/// board is closed by the barrier the [LaunchRamp] creates.
/// {@endtemplate outer_boundary}
class _OuterBoundary extends BodyComponent with InitialPosition {
/// {@macro outer_boundary}
_OuterBoundary() : super(priority: -1);
List<FixtureDef> _createFixtureDefs() {
final fixturesDefs = <FixtureDef>[];
final topWall = EdgeShape()
..set(
Vector2(3.6, 70.2),
Vector2(-14.1, 70.2),
);
final topWallFixtureDef = FixtureDef(topWall);
fixturesDefs.add(topWallFixtureDef);
final topLeftCurve = BezierCurveShape(
controlPoints: [
Vector2(-32.3, 57.2),
Vector2(-31.5, 69.9),
Vector2(-14.1, 70.2),
],
);
final topLeftCurveFixtureDef = FixtureDef(topLeftCurve);
fixturesDefs.add(topLeftCurveFixtureDef);
final leftWall = EdgeShape()
..set(
Vector2(-32.3, 57.2),
Vector2(-44.1, -44.4),
);
final leftWallFixtureDef = FixtureDef(leftWall);
fixturesDefs.add(leftWallFixtureDef);
return fixturesDefs;
}
@override
Body createBody() {
final bodyDef = BodyDef()..position = initialPosition;
final body = world.createBody(bodyDef);
_createFixtureDefs().forEach(body.createFixture);
return body;
}
@override
Future<void> onLoad() async {
await super.onLoad();
await _loadSprite();
renderBody = false;
}
Future<void> _loadSprite() async {
final sprite = await gameRef.loadSprite(
Assets.images.boundary.outer.keyName,
);
await add(
SpriteComponent(
sprite: sprite,
size: sprite.originalSize / 10,
anchor: Anchor.center,
position: Vector2(-0.2, -1.4),
),
);
}
}

@ -2,6 +2,7 @@ export 'ball.dart';
export 'baseboard.dart';
export 'board_dimensions.dart';
export 'board_side.dart';
export 'boundaries.dart';
export 'chrome_dino.dart';
export 'dash_nest_bumper.dart';
export 'dino_walls.dart';

@ -27,6 +27,7 @@ flutter:
assets:
- assets/images/
- assets/images/baseboard/
- assets/images/boundary/
- assets/images/dino/
- assets/images/flipper/
- assets/images/launch_ramp/

@ -0,0 +1,31 @@
// 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() {
group('Boundaries', () {
final tester = FlameTester(TestGame.new);
tester.testGameWidget(
'render correctly',
setUp: (game, tester) async {
await game.addFromBlueprint(Boundaries());
await game.ready();
game.camera.followVector2(Vector2.zero());
game.camera.zoom = 3.9;
},
// TODO(allisonryan0002): enable test when workflows are fixed.
// verify: (game, tester) async {
// await expectLater(
// find.byGame<Forge2DGame>(),
// matchesGoldenFile('golden/boundaries.png'),
// );
// },
);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Loading…
Cancel
Save