Merge branch 'main' into refactor/blueprint-on-load-method

pull/212/head
Alejandro Santiago 3 years ago committed by GitHub
commit c6ec8197e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -41,13 +41,30 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.boundary.outer.keyName),
images.load(components.Assets.images.spaceship.saucer.keyName),
images.load(components.Assets.images.spaceship.bridge.keyName),
images.load(components.Assets.images.spaceship.ramp.main.keyName),
images.load(components.Assets.images.spaceship.ramp.boardOpening.keyName),
images.load(
components.Assets.images.spaceship.ramp.railingForeground.keyName,
),
images.load(
components.Assets.images.spaceship.ramp.railingBackground.keyName,
),
images.load(components.Assets.images.spaceship.ramp.main.keyName),
images
.load(components.Assets.images.spaceship.ramp.arrow.inactive.keyName),
images.load(
components.Assets.images.spaceship.ramp.railingForeground.keyName,
components.Assets.images.spaceship.ramp.arrow.active1.keyName,
),
images.load(
components.Assets.images.spaceship.ramp.arrow.active2.keyName,
),
images.load(
components.Assets.images.spaceship.ramp.arrow.active3.keyName,
),
images.load(
components.Assets.images.spaceship.ramp.arrow.active4.keyName,
),
images.load(
components.Assets.images.spaceship.ramp.arrow.active5.keyName,
),
images.load(components.Assets.images.spaceship.rail.main.keyName),
images.load(components.Assets.images.spaceship.rail.foreground.keyName),

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

@ -311,6 +311,9 @@ class $AssetsImagesSpaceshipRailGen {
class $AssetsImagesSpaceshipRampGen {
const $AssetsImagesSpaceshipRampGen();
$AssetsImagesSpaceshipRampArrowGen get arrow =>
const $AssetsImagesSpaceshipRampArrowGen();
/// File path: assets/images/spaceship/ramp/board-opening.png
AssetGenImage get boardOpening =>
const AssetGenImage('assets/images/spaceship/ramp/board-opening.png');
@ -384,6 +387,34 @@ class $AssetsImagesDashBumperMainGen {
const AssetGenImage('assets/images/dash/bumper/main/inactive.png');
}
class $AssetsImagesSpaceshipRampArrowGen {
const $AssetsImagesSpaceshipRampArrowGen();
/// File path: assets/images/spaceship/ramp/arrow/active1.png
AssetGenImage get active1 =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/active1.png');
/// File path: assets/images/spaceship/ramp/arrow/active2.png
AssetGenImage get active2 =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/active2.png');
/// File path: assets/images/spaceship/ramp/arrow/active3.png
AssetGenImage get active3 =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/active3.png');
/// File path: assets/images/spaceship/ramp/arrow/active4.png
AssetGenImage get active4 =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/active4.png');
/// File path: assets/images/spaceship/ramp/arrow/active5.png
AssetGenImage get active5 =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/active5.png');
/// File path: assets/images/spaceship/ramp/arrow/inactive.png
AssetGenImage get inactive =>
const AssetGenImage('assets/images/spaceship/ramp/arrow/inactive.png');
}
class $AssetsImagesSparkyBumperAGen {
const $AssetsImagesSparkyBumperAGen();

@ -101,6 +101,8 @@ abstract class RenderPriority {
static const int spaceshipRampBackgroundRailing = _above + spaceshipRamp;
static const int spaceshipRampArrow = _above + spaceshipRamp;
static const int spaceshipRampForegroundRailing =
_above + ballOnSpaceshipRamp;

@ -2,6 +2,7 @@ import 'dart:math' as math;
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart';
import 'package:pinball_components/gen/assets.gen.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_flame/pinball_flame.dart';
@ -33,8 +34,60 @@ class SpaceshipRamp extends Blueprint {
_SpaceshipRampForegroundRailing(),
_SpaceshipRampBase()..initialPosition = Vector2(1.7, -20),
_SpaceshipRampBackgroundRailingSpriteComponent(),
SpaceshipRampArrowSpriteComponent(),
],
);
/// Forwards the sprite to the next [SpaceshipRampArrowSpriteState].
///
/// If the current state is the last one it cycles back to the initial state.
void progress() => children.firstChild<SpaceshipRampArrowSpriteComponent>()?.progress();
}
/// Indicates the state of the arrow on the [SpaceshipRamp].
@visibleForTesting
enum SpaceshipRampArrowSpriteState {
/// Arrow with no dashes lit up.
inactive,
/// Arrow with 1 light lit up.
active1,
/// Arrow with 2 lights lit up.
active2,
/// Arrow with 3 lights lit up.
active3,
/// Arrow with 4 lights lit up.
active4,
/// Arrow with all 5 lights lit up.
active5,
}
extension on SpaceshipRampArrowSpriteState {
String get path {
switch (this) {
case SpaceshipRampArrowSpriteState.inactive:
return Assets.images.spaceship.ramp.arrow.inactive.keyName;
case SpaceshipRampArrowSpriteState.active1:
return Assets.images.spaceship.ramp.arrow.active1.keyName;
case SpaceshipRampArrowSpriteState.active2:
return Assets.images.spaceship.ramp.arrow.active2.keyName;
case SpaceshipRampArrowSpriteState.active3:
return Assets.images.spaceship.ramp.arrow.active3.keyName;
case SpaceshipRampArrowSpriteState.active4:
return Assets.images.spaceship.ramp.arrow.active4.keyName;
case SpaceshipRampArrowSpriteState.active5:
return Assets.images.spaceship.ramp.arrow.active5.keyName;
}
}
SpaceshipRampArrowSpriteState get next {
return SpaceshipRampArrowSpriteState
.values[(index + 1) % SpaceshipRampArrowSpriteState.values.length];
}
}
class _SpaceshipRampBackground extends BodyComponent
@ -113,19 +166,21 @@ class _SpaceshipRampBackgroundRailingSpriteComponent extends SpriteComponent
with HasGameRef {
_SpaceshipRampBackgroundRailingSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(-11.7, -54.3),
priority: RenderPriority.spaceshipRampBackgroundRailing,
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
Assets.images.spaceship.ramp.railingBackground.keyName,
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.spaceship.ramp.railingBackground.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
anchor = Anchor.center;
position = Vector2(-11.7, -54.3);
}
}
@ -134,13 +189,50 @@ class _SpaceshipRampBackgroundRampSpriteComponent extends SpriteComponent
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
Assets.images.spaceship.ramp.main.keyName,
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.spaceship.ramp.main.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
anchor = Anchor.center;
position = Vector2(-11.7, -53.6);
position = Vector2(-10.7, -53.6);
}
}
/// {@template spaceship_ramp_arrow_sprite_component}
/// An arrow inside [SpaceshipRamp].
///
/// Lights up a each dash whenever a [Ball] gets into [SpaceshipRamp].
/// {@endtemplate}
class SpaceshipRampArrowSpriteComponent
extends SpriteGroupComponent<SpaceshipRampArrowSpriteState>
with HasGameRef {
/// {@macro spaceship_ramp_arrow_sprite_component}
SpaceshipRampArrowSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(-3.9, -56.5),
priority: RenderPriority.spaceshipRampArrow,
);
/// Changes arrow image to the next [Sprite].
void progress() => current = current?.next;
@override
Future<void> onLoad() async {
await super.onLoad();
final sprites = <SpaceshipRampArrowSpriteState, Sprite>{};
this.sprites = sprites;
for (final spriteState in SpaceshipRampArrowSpriteState.values) {
sprites[spriteState] = Sprite(
gameRef.images.fromCache(spriteState.path),
);
}
current = SpaceshipRampArrowSpriteState.inactive;
size = sprites[current]!.originalSize / 10;
}
}
@ -149,8 +241,10 @@ class _SpaceshipRampBoardOpeningSpriteComponent extends SpriteComponent
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
Assets.images.spaceship.ramp.boardOpening.keyName,
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.spaceship.ramp.boardOpening.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
@ -221,16 +315,22 @@ class _SpaceshipRampForegroundRailing extends BodyComponent
class _SpaceshipRampForegroundRailingSpriteComponent extends SpriteComponent
with HasGameRef {
_SpaceshipRampForegroundRailingSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(-12.3, -52.5),
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
Assets.images.spaceship.ramp.railingForeground.keyName,
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.spaceship.ramp.railingForeground.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
anchor = Anchor.center;
position = Vector2(-12.3, -52.5);
}
}

@ -52,6 +52,7 @@ flutter:
- assets/images/spaceship/
- assets/images/spaceship/rail/
- assets/images/spaceship/ramp/
- assets/images/spaceship/ramp/arrow/
- assets/images/chrome_dino/
- assets/images/kicker/
- assets/images/plunger/

@ -2,11 +2,12 @@ import 'dart:async';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SpaceshipRampGame extends BasicBallGame {
class SpaceshipRampGame extends BasicBallGame with KeyboardEvents {
SpaceshipRampGame()
: super(
color: Colors.blue,
@ -19,13 +20,45 @@ class SpaceshipRampGame extends BasicBallGame {
- Activate the "trace" parameter to overlay the body.
- Tap anywhere on the screen to spawn a ball into the game.
- Press space to progress arrow sprites.
''';
late final SpaceshipRamp _spaceshipRamp;
@override
Future<void> onLoad() async {
await super.onLoad();
await addFromBlueprint(SpaceshipRamp());
await images.loadAll([
Assets.images.spaceship.ramp.railingBackground.keyName,
Assets.images.spaceship.ramp.main.keyName,
Assets.images.spaceship.ramp.boardOpening.keyName,
Assets.images.spaceship.ramp.railingForeground.keyName,
Assets.images.spaceship.ramp.arrow.inactive.keyName,
Assets.images.spaceship.ramp.arrow.active1.keyName,
Assets.images.spaceship.ramp.arrow.active2.keyName,
Assets.images.spaceship.ramp.arrow.active3.keyName,
Assets.images.spaceship.ramp.arrow.active4.keyName,
Assets.images.spaceship.ramp.arrow.active5.keyName,
]);
_spaceshipRamp = SpaceshipRamp();
await addFromBlueprint(_spaceshipRamp);
camera.followVector2(Vector2(-12, -50));
await traceAllBodies();
}
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
if (event is RawKeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.space) {
_spaceshipRamp.progress();
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

@ -1,5 +1,6 @@
// ignore_for_file: cascade_invocations
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
@ -9,22 +10,197 @@ import 'package:pinball_flame/pinball_flame.dart';
import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.spaceship.ramp.boardOpening.keyName,
Assets.images.spaceship.ramp.railingForeground.keyName,
Assets.images.spaceship.ramp.railingBackground.keyName,
Assets.images.spaceship.ramp.main.keyName,
Assets.images.spaceship.ramp.arrow.inactive.keyName,
Assets.images.spaceship.ramp.arrow.active1.keyName,
Assets.images.spaceship.ramp.arrow.active2.keyName,
Assets.images.spaceship.ramp.arrow.active3.keyName,
Assets.images.spaceship.ramp.arrow.active4.keyName,
Assets.images.spaceship.ramp.arrow.active5.keyName,
];
final flameTester = FlameTester(() => TestGame(assets));
group('SpaceshipRamp', () {
final tester = FlameTester(TestGame.new);
tester.testGameWidget(
'renders correctly',
setUp: (game, tester) async {
await game.addFromBlueprint(SpaceshipRamp());
game.camera.followVector2(Vector2(-13, -50));
await game.ready();
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship-ramp.png'),
);
flameTester.test(
'loads correctly',
(game) async {
final spaceshipRamp = SpaceshipRamp();
await game.ensureAdd(spaceshipRamp);
expect(game.contains(spaceshipRamp), isTrue);
},
);
group('renders correctly', () {
final centerForSpaceshipRamp = Vector2(-13, -55);
flameTester.testGameWidget(
'inactive sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.inactive,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/inactive.png'),
);
},
);
flameTester.testGameWidget(
'active1 sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
spaceshipRamp.progress();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.active1,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/active1.png'),
);
},
);
flameTester.testGameWidget(
'active2 sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
spaceshipRamp
..progress()
..progress();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.active2,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/active2.png'),
);
},
);
flameTester.testGameWidget(
'active3 sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
spaceshipRamp
..progress()
..progress()
..progress();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.active3,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/active3.png'),
);
},
);
flameTester.testGameWidget(
'active4 sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
spaceshipRamp
..progress()
..progress()
..progress()
..progress();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.active4,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/active4.png'),
);
},
);
flameTester.testGameWidget(
'active5 sprite',
setUp: (game, tester) async {
await game.images.loadAll(assets);
final spaceshipRamp = SpaceshipRamp();
await game.addFromBlueprint(spaceshipRamp);
await game.ready();
spaceshipRamp
..progress()
..progress()
..progress()
..progress()
..progress();
await tester.pump();
expect(
spaceshipRamp.spaceshipRampArrow.current,
SpaceshipRampArrowSpriteState.active5,
);
game.camera.followVector2(centerForSpaceshipRamp);
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/spaceship_ramp/active5.png'),
);
},
);
});
});
}

@ -33,6 +33,16 @@ void main() {
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.spaceship.ramp.boardOpening.keyName,
Assets.images.spaceship.ramp.railingForeground.keyName,
Assets.images.spaceship.ramp.railingBackground.keyName,
Assets.images.spaceship.ramp.main.keyName,
Assets.images.spaceship.ramp.arrow.inactive.keyName,
Assets.images.spaceship.ramp.arrow.active1.keyName,
Assets.images.spaceship.ramp.arrow.active2.keyName,
Assets.images.spaceship.ramp.arrow.active3.keyName,
Assets.images.spaceship.ramp.arrow.active4.keyName,
Assets.images.spaceship.ramp.arrow.active5.keyName,
];
final flameTester = FlameTester(() => PinballTestGame(assets));
final debugModeFlameTester = FlameTester(() => DebugPinballTestGame(assets));

Loading…
Cancel
Save