Merge branch 'main' into refactor/remove-component-from-blueprint

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

@ -0,0 +1,18 @@
name: share_repository
on:
push:
paths:
- "packages/share_repository/**"
- ".github/workflows/share_repository.yaml"
pull_request:
paths:
- "packages/share_repository/**"
- ".github/workflows/share_repository.yaml"
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
working_directory: packages/share_repository

@ -4,7 +4,6 @@ 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 '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';

@ -62,10 +62,13 @@ class BallController extends ComponentController<Ball>
Future<void> turboCharge() async { Future<void> turboCharge() async {
gameRef.read<GameBloc>().add(const SparkyTurboChargeActivated()); gameRef.read<GameBloc>().add(const SparkyTurboChargeActivated());
// TODO(allisonryan0002): adjust delay to match animation duration once
// given animations.
component.stop(); component.stop();
await Future<void>.delayed(const Duration(seconds: 1)); // TODO(alestiago): Refactor this hard coded duration once the following is
// merged:
// https://github.com/flame-engine/flame/pull/1564
await Future<void>.delayed(
const Duration(milliseconds: 2583),
);
component.resume(); component.resume();
await component.boost(Vector2(40, 110)); await component.boost(Vector2(40, 110));
} }

@ -1,52 +0,0 @@
// ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template controlled_sparky_computer}
/// [SparkyComputer] with a [SparkyComputerController] attached.
/// {@endtemplate}
class ControlledSparkyComputer extends SparkyComputer
with Controls<SparkyComputerController>, HasGameRef<Forge2DGame> {
/// {@macro controlled_sparky_computer}
ControlledSparkyComputer() : super() {
controller = SparkyComputerController(this);
}
@override
Future<void> onLoad() async {
await super.onLoad();
gameRef.addContactCallback(SparkyComputerSensorBallContactCallback());
}
}
/// {@template sparky_computer_controller}
/// Controller attached to a [SparkyComputer] that handles its game related
/// logic.
/// {@endtemplate}
// TODO(allisonryan0002): listen for turbo charge game bonus and animate Sparky.
class SparkyComputerController
extends ComponentController<ControlledSparkyComputer> {
/// {@macro sparky_computer_controller}
SparkyComputerController(ControlledSparkyComputer controlledComputer)
: super(controlledComputer);
}
/// {@template sparky_computer_sensor_ball_contact_callback}
/// Turbo charges the [Ball] when it enters the [SparkyComputer]
/// {@endtemplate}
@visibleForTesting
class SparkyComputerSensorBallContactCallback
extends ContactCallback<SparkyComputerSensor, ControlledBall> {
/// {@macro sparky_computer_sensor_ball_contact_callback}
SparkyComputerSensorBallContactCallback();
@override
void begin(_, ControlledBall ball, __) {
ball.controller.turboCharge();
}
}

@ -1,10 +1,10 @@
// ignore_for_file: avoid_renaming_method_parameters // ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template sparky_fire_zone} /// {@template sparky_fire_zone}
/// Area positioned at the top left of the [Board] where the [Ball] /// Area positioned at the top left of the [Board] where the [Ball]
@ -12,29 +12,21 @@ import 'package:pinball_components/pinball_components.dart';
/// ///
/// When a [Ball] hits [SparkyBumper]s, the bumper animates. /// When a [Ball] hits [SparkyBumper]s, the bumper animates.
/// {@endtemplate} /// {@endtemplate}
class SparkyFireZone extends Component with HasGameRef<PinballGame> { class SparkyFireZone extends Blueprint {
/// {@macro sparky_fire_zone} /// {@macro sparky_fire_zone}
SparkyFireZone(); SparkyFireZone()
: super(
@override components: [
Future<void> onLoad() async { _SparkyBumper.a()..initialPosition = Vector2(-22.9, -41.65),
await super.onLoad(); _SparkyBumper.b()..initialPosition = Vector2(-21.25, -57.9),
_SparkyBumper.c()..initialPosition = Vector2(-3.3, -52.55),
gameRef.addContactCallback(SparkyBumperBallContactCallback()); SparkyComputerSensor()..initialPosition = Vector2(-13, -49.8),
SparkyAnimatronic()..position = Vector2(-13.8, -58.2),
final lowerLeftBumper = _SparkyBumper.a() ],
..initialPosition = Vector2(-22.9, -41.65); blueprints: [
final upperLeftBumper = _SparkyBumper.b() SparkyComputer(),
..initialPosition = Vector2(-21.25, -57.9); ],
final rightBumper = _SparkyBumper.c() );
..initialPosition = Vector2(-3.3, -52.55);
await addAll([
lowerLeftBumper,
upperLeftBumper,
rightBumper,
]);
}
} }
// TODO(alestiago): Revisit ScorePoints logic once the FlameForge2D // TODO(alestiago): Revisit ScorePoints logic once the FlameForge2D
@ -48,6 +40,14 @@ class _SparkyBumper extends SparkyBumper with ScorePoints {
@override @override
int get points => 20; int get points => 20;
@override
Future<void> onLoad() async {
await super.onLoad();
// TODO(alestiago): Revisit once this has been merged:
// https://github.com/flame-engine/flame/pull/1547
gameRef.addContactCallback(SparkyBumperBallContactCallback());
}
} }
/// Listens when a [Ball] bounces bounces against a [SparkyBumper]. /// Listens when a [Ball] bounces bounces against a [SparkyBumper].
@ -63,3 +63,48 @@ class SparkyBumperBallContactCallback
sparkyBumper.animate(); sparkyBumper.animate();
} }
} }
/// {@template sparky_computer_sensor}
/// Small sensor body used to detect when a ball has entered the
/// [SparkyComputer].
/// {@endtemplate}
// TODO(alestiago): Revisit once this has been merged:
// https://github.com/flame-engine/flame/pull/1547
class SparkyComputerSensor extends BodyComponent with InitialPosition {
/// {@macro sparky_computer_sensor}
SparkyComputerSensor() {
renderBody = false;
}
@override
Body createBody() {
final shape = CircleShape()..radius = 0.1;
final fixtureDef = FixtureDef(shape, isSensor: true);
final bodyDef = BodyDef(
position: initialPosition,
userData: this,
);
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
@override
Future<void> onLoad() async {
await super.onLoad();
// TODO(alestiago): Revisit once this has been merged:
// https://github.com/flame-engine/flame/pull/1547
gameRef.addContactCallback(SparkyComputerSensorBallContactCallback());
}
}
@visibleForTesting
// TODO(alestiago): Revisit once this has been merged:
// https://github.com/flame-engine/flame/pull/1547
// ignore: public_member_api_docs
class SparkyComputerSensorBallContactCallback
extends ContactCallback<SparkyComputerSensor, ControlledBall> {
@override
void begin(_, ControlledBall controlledBall, __) {
controlledBall.controller.turboCharge();
controlledBall.gameRef.firstChild<SparkyAnimatronic>()?.playing = true;
}
}

@ -43,8 +43,11 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.dash.bumper.b.inactive.keyName), images.load(components.Assets.images.dash.bumper.b.inactive.keyName),
images.load(components.Assets.images.dash.bumper.main.active.keyName), images.load(components.Assets.images.dash.bumper.main.active.keyName),
images.load(components.Assets.images.dash.bumper.main.inactive.keyName), images.load(components.Assets.images.dash.bumper.main.inactive.keyName),
images.load(components.Assets.images.plunger.plunger.keyName),
images.load(components.Assets.images.plunger.rocket.keyName),
images.load(components.Assets.images.boundary.bottom.keyName), images.load(components.Assets.images.boundary.bottom.keyName),
images.load(components.Assets.images.boundary.outer.keyName), images.load(components.Assets.images.boundary.outer.keyName),
images.load(components.Assets.images.boundary.outerBottom.keyName),
images.load(components.Assets.images.spaceship.saucer.keyName), images.load(components.Assets.images.spaceship.saucer.keyName),
images.load(components.Assets.images.spaceship.bridge.keyName), images.load(components.Assets.images.spaceship.bridge.keyName),
images.load(components.Assets.images.spaceship.ramp.boardOpening.keyName), images.load(components.Assets.images.spaceship.ramp.boardOpening.keyName),
@ -80,12 +83,11 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.alienBumper.b.inactive.keyName), images.load(components.Assets.images.alienBumper.b.inactive.keyName),
images.load(components.Assets.images.chromeDino.mouth.keyName), images.load(components.Assets.images.chromeDino.mouth.keyName),
images.load(components.Assets.images.chromeDino.head.keyName), images.load(components.Assets.images.chromeDino.head.keyName),
images.load(components.Assets.images.plunger.plunger.keyName),
images.load(components.Assets.images.plunger.rocket.keyName),
images.load(components.Assets.images.sparky.computer.base.keyName),
images.load(components.Assets.images.sparky.computer.top.keyName), images.load(components.Assets.images.sparky.computer.top.keyName),
images.load(components.Assets.images.sparky.bumper.a.active.keyName), images.load(components.Assets.images.sparky.computer.base.keyName),
images.load(components.Assets.images.sparky.animatronic.keyName),
images.load(components.Assets.images.sparky.bumper.a.inactive.keyName), images.load(components.Assets.images.sparky.bumper.a.inactive.keyName),
images.load(components.Assets.images.sparky.bumper.a.active.keyName),
images.load(components.Assets.images.sparky.bumper.b.active.keyName), images.load(components.Assets.images.sparky.bumper.b.active.keyName),
images.load(components.Assets.images.sparky.bumper.b.inactive.keyName), images.load(components.Assets.images.sparky.bumper.b.inactive.keyName),
images.load(components.Assets.images.sparky.bumper.c.active.keyName), images.load(components.Assets.images.sparky.bumper.c.active.keyName),

@ -2,6 +2,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
@ -49,13 +50,13 @@ class PinballGame extends Forge2DGame
// TODO(allisonryan0002): banish Wall and Board classes in later PR. // TODO(allisonryan0002): banish Wall and Board classes in later PR.
await add(BottomWall()); await add(BottomWall());
unawaited(addFromBlueprint(Boundaries())); unawaited(addFromBlueprint(Boundaries()));
unawaited(addFromBlueprint(ControlledSparkyComputer())); unawaited(addFromBlueprint(LaunchRamp()));
final launcher = Launcher(); final launcher = Launcher();
unawaited(addFromBlueprint(launcher)); unawaited(addFromBlueprint(launcher));
unawaited(add(Board())); unawaited(add(Board()));
unawaited(add(AlienZone())); unawaited(add(AlienZone()));
unawaited(add(SparkyFireZone())); await addFromBlueprint(SparkyFireZone());
unawaited(addFromBlueprint(Slingshots())); unawaited(addFromBlueprint(Slingshots()));
unawaited(addFromBlueprint(DinoWalls())); unawaited(addFromBlueprint(DinoWalls()));
unawaited(_addBonusWord()); unawaited(_addBonusWord());
@ -134,7 +135,7 @@ class _GameBallsController extends ComponentController<PinballGame>
} }
} }
class DebugPinballGame extends PinballGame with TapDetector { class DebugPinballGame extends PinballGame with FPSCounter, TapDetector {
DebugPinballGame({ DebugPinballGame({
required PinballTheme theme, required PinballTheme theme,
required PinballAudio audio, required PinballAudio audio,
@ -149,6 +150,7 @@ class DebugPinballGame extends PinballGame with TapDetector {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await _loadBackground(); await _loadBackground();
await add(_DebugInformation());
} }
// TODO(alestiago): Move to PinballGame once we have the real background // TODO(alestiago): Move to PinballGame once we have the real background
@ -191,3 +193,35 @@ class _DebugGameBallsController extends _GameBallsController {
return noBallsLeft && canBallRespawn; return noBallsLeft && canBallRespawn;
} }
} }
class _DebugInformation extends Component with HasGameRef<DebugPinballGame> {
_DebugInformation() : super(priority: RenderPriority.debugInfo);
@override
PositionType get positionType => PositionType.widget;
final _debugTextPaint = TextPaint(
style: const TextStyle(
color: Colors.green,
fontSize: 10,
),
);
final _debugBackgroundPaint = Paint()..color = Colors.white;
@override
void render(Canvas canvas) {
final debugText = [
'FPS: ${gameRef.fps().toStringAsFixed(1)}',
'BALLS: ${gameRef.descendants().whereType<ControlledBall>().length}',
].join(' | ');
final height = _debugTextPaint.measureTextHeight(debugText);
final position = Vector2(0, gameRef.camera.canvasSize.y - height);
canvas.drawRect(
position & Vector2(gameRef.camera.canvasSize.x, height),
_debugBackgroundPaint,
);
_debugTextPaint.render(canvas, debugText, position);
}
}

@ -36,7 +36,7 @@ extension LeaderboardEntryDataX on LeaderboardEntryData {
rank: position.toString(), rank: position.toString(),
playerInitials: playerInitials, playerInitials: playerInitials,
score: score, score: score,
character: character.toTheme.character, character: character.toTheme.leaderboardIcon,
); );
} }
} }

@ -124,7 +124,7 @@ class CharacterImageButton extends StatelessWidget {
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: characterTheme.character.image(), child: characterTheme.icon.image(),
), ),
), ),
); );

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

@ -86,6 +86,10 @@ class $AssetsImagesBoundaryGen {
AssetGenImage get bottom => AssetGenImage get bottom =>
const AssetGenImage('assets/images/boundary/bottom.png'); const AssetGenImage('assets/images/boundary/bottom.png');
/// File path: assets/images/boundary/outer-bottom.png
AssetGenImage get outerBottom =>
const AssetGenImage('assets/images/boundary/outer-bottom.png');
/// File path: assets/images/boundary/outer.png /// File path: assets/images/boundary/outer.png
AssetGenImage get outer => AssetGenImage get outer =>
const AssetGenImage('assets/images/boundary/outer.png'); const AssetGenImage('assets/images/boundary/outer.png');
@ -257,6 +261,8 @@ class $AssetsImagesSpaceshipGen {
class $AssetsImagesSparkyGen { class $AssetsImagesSparkyGen {
const $AssetsImagesSparkyGen(); const $AssetsImagesSparkyGen();
AssetGenImage get animatronic =>
const AssetGenImage('assets/images/sparky/animatronic.png');
$AssetsImagesSparkyBumperGen get bumper => $AssetsImagesSparkyBumperGen get bumper =>
const $AssetsImagesSparkyBumperGen(); const $AssetsImagesSparkyBumperGen();
$AssetsImagesSparkyComputerGen get computer => $AssetsImagesSparkyComputerGen get computer =>

@ -13,6 +13,7 @@ class Boundaries extends Blueprint {
components: [ components: [
_BottomBoundary(), _BottomBoundary(),
_OuterBoundary(), _OuterBoundary(),
_OuterBottomBoundarySpriteComponent(),
], ],
); );
} }
@ -91,8 +92,10 @@ class _OuterBoundary extends BodyComponent with InitialPosition {
/// {@macro outer_boundary} /// {@macro outer_boundary}
_OuterBoundary() _OuterBoundary()
: super( : super(
priority: RenderPriority.outerBoudary, priority: RenderPriority.outerBoundary,
children: [_OuterBoundarySpriteComponent()], children: [
_OuterBoundarySpriteComponent(),
],
) { ) {
renderBody = false; renderBody = false;
} }
@ -157,3 +160,25 @@ class _OuterBoundarySpriteComponent extends SpriteComponent with HasGameRef {
size = sprite.originalSize / 10; size = sprite.originalSize / 10;
} }
} }
class _OuterBottomBoundarySpriteComponent extends SpriteComponent
with HasGameRef {
_OuterBottomBoundarySpriteComponent()
: super(
priority: RenderPriority.outerBottomBoundary,
anchor: Anchor.center,
position: Vector2(0, 71),
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.boundary.outerBottom.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
}
}

@ -29,5 +29,6 @@ export 'slingshot.dart';
export 'spaceship.dart'; export 'spaceship.dart';
export 'spaceship_rail.dart'; export 'spaceship_rail.dart';
export 'spaceship_ramp.dart'; export 'spaceship_ramp.dart';
export 'sparky_animatronic.dart';
export 'sparky_bumper.dart'; export 'sparky_bumper.dart';
export 'sparky_computer.dart'; export 'sparky_computer.dart';

@ -38,17 +38,9 @@ class DashAnimatronic extends SpriteAnimationComponent with HasGameRef {
textureSize: textureSize, textureSize: textureSize,
loop: false, loop: false,
), ),
); )..onComplete = () {
} animation?.reset();
@override
void update(double dt) {
super.update(dt);
if (animation != null) {
if (animation!.isLastFrame) {
animation!.reset();
playing = false; playing = false;
} };
}
} }
} }

@ -78,6 +78,7 @@ class _GoogleLetterSprite extends SpriteComponent with HasGameRef {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
// TODO(alestiago): Used cached assets.
final sprite = await gameRef.loadSprite(_path); final sprite = await gameRef.loadSprite(_path);
this.sprite = sprite; this.sprite = sprite;
// TODO(alestiago): Size correctly once the assets are provided. // TODO(alestiago): Size correctly once the assets are provided.

@ -136,6 +136,7 @@ class _KickerSpriteComponent extends SpriteComponent with HasGameRef {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
// TODO(alestiago): Used cached asset.
final sprite = await gameRef.loadSprite( final sprite = await gameRef.loadSprite(
(_side.isLeft) (_side.isLeft)
? Assets.images.kicker.left.keyName ? Assets.images.kicker.left.keyName

@ -148,6 +148,7 @@ class _PlungerSpriteAnimationGroupComponent
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
// TODO(alestiago): Used cached images.
final spriteSheet = await gameRef.images.load( final spriteSheet = await gameRef.images.load(
Assets.images.plunger.plunger.keyName, Assets.images.plunger.plunger.keyName,
); );

@ -39,7 +39,9 @@ abstract class RenderPriority {
static const int bottomBoundary = _above + dinoBottomWall; static const int bottomBoundary = _above + dinoBottomWall;
static const int outerBoudary = _above + background; static const int outerBoundary = _above + background;
static const int outerBottomBoundary = _above + rocket;
// Bottom Group // Bottom Group
@ -47,7 +49,7 @@ abstract class RenderPriority {
// Launcher // Launcher
static const int launchRamp = _above + outerBoudary; static const int launchRamp = _above + outerBoundary;
static const int launchRampForegroundRailing = _below + ballOnBoard; static const int launchRampForegroundRailing = _below + ballOnBoard;
@ -113,4 +115,7 @@ abstract class RenderPriority {
// Score Text // Score Text
static const int scoreText = _above + spaceshipRampForegroundRailing; static const int scoreText = _above + spaceshipRampForegroundRailing;
// Debug information
static const int debugInfo = _above + scoreText;
} }

@ -0,0 +1,46 @@
import 'package:flame/components.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template sparky_animatronic}
/// Animated Sparky that sits on top of the [SparkyComputer].
/// {@endtemplate}
class SparkyAnimatronic extends SpriteAnimationComponent with HasGameRef {
/// {@macro sparky_animatronic}
SparkyAnimatronic()
: super(
anchor: Anchor.center,
playing: false,
priority: RenderPriority.sparkyAnimatronic,
);
@override
Future<void> onLoad() async {
await super.onLoad();
final spriteSheet = gameRef.images.fromCache(
Assets.images.sparky.animatronic.keyName,
);
const amountPerRow = 9;
const amountPerColumn = 7;
final textureSize = Vector2(
spriteSheet.width / amountPerRow,
spriteSheet.height / amountPerColumn,
);
size = textureSize / 10;
animation = SpriteAnimation.fromFrameData(
spriteSheet,
SpriteAnimationData.sequenced(
amount: (amountPerRow * amountPerColumn) - 1,
amountPerRow: amountPerRow,
stepTime: 1 / 24,
textureSize: textureSize,
loop: false,
),
)..onComplete = () {
animation?.reset();
playing = false;
};
}
}

@ -7,9 +7,6 @@ import 'package:pinball_flame/pinball_flame.dart';
/// {@template sparky_computer} /// {@template sparky_computer}
/// A computer owned by Sparky. /// A computer owned by Sparky.
///
/// Register a [ContactCallback] for [SparkyComputerSensor] to listen when
/// something enters the [SparkyComputer].
/// {@endtemplate} /// {@endtemplate}
class SparkyComputer extends Blueprint { class SparkyComputer extends Blueprint {
/// {@macro sparky_computer} /// {@macro sparky_computer}
@ -18,7 +15,6 @@ class SparkyComputer extends Blueprint {
components: [ components: [
_ComputerBase(), _ComputerBase(),
_ComputerTopSpriteComponent(), _ComputerTopSpriteComponent(),
SparkyComputerSensor(),
], ],
); );
} }
@ -104,24 +100,3 @@ class _ComputerTopSpriteComponent extends SpriteComponent with HasGameRef {
size = sprite.originalSize / 10; size = sprite.originalSize / 10;
} }
} }
/// {@template sparky_computer_sensor}
/// Small sensor body used to detect when a ball has entered the
/// [SparkyComputer].
/// {@endtemplate}
class SparkyComputerSensor extends BodyComponent with InitialPosition {
/// {@macro sparky_computer_sensor}
SparkyComputerSensor() {
renderBody = false;
}
@override
Body createBody() {
final shape = CircleShape()..radius = 0.1;
final fixtureDef = FixtureDef(shape, isSensor: true);
final bodyDef = BodyDef()
..position = initialPosition
..userData = this;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}

@ -61,6 +61,7 @@ flutter:
- assets/images/slingshot/ - assets/images/slingshot/
- assets/images/alien_bumper/a/ - assets/images/alien_bumper/a/
- assets/images/alien_bumper/b/ - assets/images/alien_bumper/b/
- assets/images/sparky/
- assets/images/sparky/computer/ - assets/images/sparky/computer/
- assets/images/sparky/bumper/a/ - assets/images/sparky/bumper/a/
- assets/images/sparky/bumper/b/ - assets/images/sparky/bumper/b/

@ -0,0 +1,36 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
const _path =
'https://github.com/VGVentures/pinball/tree/main/packages/pinball_components/sandbox/lib/stories/';
extension StoryAddGame on Story {
void addGame({
required String title,
required String description,
required Game Function(DashbookContext) gameBuilder,
}) {
final _chapter = Chapter(
title,
(DashbookContext context) {
final game = gameBuilder(context);
if (game is Traceable) {
game.trace = context.boolProperty('Trace', true);
}
return GameWidget(game: game);
},
this,
codeLink: '$_path${name.toPath()}/${title.toPath()}',
info: description,
);
chapters.add(_chapter);
}
}
extension on String {
String toPath() {
return replaceAll(' ', '_')..toLowerCase();
}
}

@ -1,3 +1,3 @@
export 'add_game.dart';
export 'games.dart'; export 'games.dart';
export 'methods.dart';
export 'trace.dart'; export 'trace.dart';

@ -5,16 +5,25 @@ import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
abstract class BasicGame extends Forge2DGame { abstract class AssetsGame extends Forge2DGame {
BasicGame() { AssetsGame({
List<String>? imagesFileNames,
}) : _imagesFileNames = imagesFileNames {
images.prefix = ''; images.prefix = '';
} }
}
abstract class BasicKeyboardGame extends BasicGame final List<String>? _imagesFileNames;
with HasKeyboardHandlerComponents {}
@override
Future<void> onLoad() async {
await super.onLoad();
if (_imagesFileNames != null) {
await images.loadAll(_imagesFileNames!);
}
}
}
abstract class LineGame extends BasicGame with PanDetector { abstract class LineGame extends AssetsGame with PanDetector {
Vector2? _lineEnd; Vector2? _lineEnd;
@override @override

@ -1,3 +0,0 @@
String buildSourceLink(String path) {
return 'https://github.com/VGVentures/pinball/tree/main/packages/pinball_components/sandbox/lib/stories/$path';
}

@ -35,7 +35,7 @@ mixin Traceable on Forge2DGame {
.forEach((bodyComponent) => bodyComponent.trace()); .forEach((bodyComponent) => bodyComponent.trace());
descendants() descendants()
.whereType<SpriteComponent>() .whereType<HasPaint>()
.forEach((sprite) => sprite.setOpacity(0.5)); .forEach((sprite) => sprite.setOpacity(0.5));
} }
} }

@ -16,9 +16,6 @@ void main() {
addLayerStories(dashbook); addLayerStories(dashbook);
addEffectsStories(dashbook); addEffectsStories(dashbook);
addFlipperStories(dashbook); addFlipperStories(dashbook);
addSpaceshipStories(dashbook);
addSpaceshipRampStories(dashbook);
addSpaceshipRailStories(dashbook);
addBaseboardStories(dashbook); addBaseboardStories(dashbook);
addChromeDinoStories(dashbook); addChromeDinoStories(dashbook);
addDashNestBumperStories(dashbook); addDashNestBumperStories(dashbook);
@ -27,7 +24,6 @@ void main() {
addSlingshotStories(dashbook); addSlingshotStories(dashbook);
addSparkyBumperStories(dashbook); addSparkyBumperStories(dashbook);
addAlienZoneStories(dashbook); addAlienZoneStories(dashbook);
addZoomStories(dashbook);
addBoundariesStories(dashbook); addBoundariesStories(dashbook);
addGoogleWordStories(dashbook); addGoogleWordStories(dashbook);
addLaunchRampStories(dashbook); addLaunchRampStories(dashbook);

@ -4,10 +4,17 @@ import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class AlienBumperAGame extends BasicBallGame { class AlienBumperAGame extends BallGame {
AlienBumperAGame() : super(color: const Color(0xFF0000FF)); AlienBumperAGame()
: super(
color: const Color(0xFF0000FF),
imagesFileNames: [
Assets.images.alienBumper.a.active.keyName,
Assets.images.alienBumper.a.inactive.keyName,
],
);
static const info = ''' static const description = '''
Shows how a AlienBumperA is rendered. Shows how a AlienBumperA is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -17,16 +24,10 @@ class AlienBumperAGame extends BasicBallGame {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([ camera.followVector2(Vector2.zero());
Assets.images.alienBumper.a.active.keyName, await add(
Assets.images.alienBumper.a.inactive.keyName, AlienBumper.a()..priority = 1,
]); );
final center = screenToWorld(camera.viewport.canvasSize! / 2);
final alienBumperA = AlienBumper.a()
..initialPosition = Vector2(center.x - 20, center.y - 20)
..priority = 1;
await add(alienBumperA);
await traceAllBodies(); await traceAllBodies();
} }

@ -4,10 +4,17 @@ import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class AlienBumperBGame extends BasicBallGame { class AlienBumperBGame extends BallGame {
AlienBumperBGame() : super(color: const Color(0xFF0000FF)); AlienBumperBGame()
: super(
color: const Color(0xFF0000FF),
imagesFileNames: [
Assets.images.alienBumper.b.active.keyName,
Assets.images.alienBumper.b.inactive.keyName,
],
);
static const info = ''' static const description = '''
Shows how a AlienBumperB is rendered. Shows how a AlienBumperB is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -17,16 +24,10 @@ class AlienBumperBGame extends BasicBallGame {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([ camera.followVector2(Vector2.zero());
Assets.images.alienBumper.b.active.keyName, await add(
Assets.images.alienBumper.b.inactive.keyName, AlienBumper.b()..priority = 1,
]); );
final center = screenToWorld(camera.viewport.canvasSize! / 2);
final alienBumperB = AlienBumper.b()
..initialPosition = Vector2(center.x - 10, center.y + 10)
..priority = 1;
await add(alienBumperB);
await traceAllBodies(); await traceAllBodies();
} }

@ -6,8 +6,8 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BasicSpaceshipGame extends BasicGame with TapDetector { class SpaceshipGame extends AssetsGame with TapDetector {
static const info = ''' static const description = '''
Shows how a Spaceship works. Shows how a Spaceship works.
- Tap anywhere on the screen to spawn a Ball into the game. - Tap anywhere on the screen to spawn a Ball into the game.
@ -18,10 +18,10 @@ class BasicSpaceshipGame extends BasicGame with TapDetector {
await super.onLoad(); await super.onLoad();
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await addFromBlueprint(
unawaited( Spaceship(position: Vector2.zero()),
addFromBlueprint(Spaceship(position: Vector2.zero())),
); );
await ready();
} }
@override @override

@ -6,7 +6,7 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SpaceshipRailGame extends BasicBallGame { class SpaceshipRailGame extends BallGame {
SpaceshipRailGame() SpaceshipRailGame()
: super( : super(
color: Colors.blue, color: Colors.blue,
@ -14,7 +14,7 @@ class SpaceshipRailGame extends BasicBallGame {
ballLayer: Layer.spaceshipExitRail, ballLayer: Layer.spaceshipExitRail,
); );
static const info = ''' static const description = '''
Shows how SpaceshipRail are rendered. Shows how SpaceshipRail are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -26,10 +26,8 @@ class SpaceshipRailGame extends BasicBallGame {
await super.onLoad(); await super.onLoad();
camera.followVector2(Vector2(-30, -10)); camera.followVector2(Vector2(-30, -10));
await addFromBlueprint(SpaceshipRail());
final spaceshipRail = SpaceshipRail(); await ready();
unawaited(addFromBlueprint(spaceshipRail));
await traceAllBodies(); await traceAllBodies();
} }
} }

@ -7,15 +7,27 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SpaceshipRampGame extends BasicBallGame with KeyboardEvents { class SpaceshipRampGame extends BallGame with KeyboardEvents {
SpaceshipRampGame() SpaceshipRampGame()
: super( : super(
color: Colors.blue, color: Colors.blue,
ballPriority: RenderPriority.ballOnSpaceshipRamp, ballPriority: RenderPriority.ballOnSpaceshipRamp,
ballLayer: Layer.spaceshipEntranceRamp, ballLayer: Layer.spaceshipEntranceRamp,
imagesFileNames: [
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,
],
); );
static const info = ''' static const description = '''
Shows how SpaceshipRamp is rendered. Shows how SpaceshipRamp is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -29,22 +41,10 @@ class SpaceshipRampGame extends BasicBallGame with KeyboardEvents {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
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)); camera.followVector2(Vector2(-12, -50));
await addFromBlueprint(
_spaceshipRamp = SpaceshipRamp(),
);
await traceAllBodies(); await traceAllBodies();
} }

@ -1,25 +1,36 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/alien_zone/alien_bumper_a_game.dart'; import 'package:sandbox/stories/alien_zone/alien_bumper_a_game.dart';
import 'package:sandbox/stories/alien_zone/alien_bumper_b_game.dart'; import 'package:sandbox/stories/alien_zone/alien_bumper_b_game.dart';
import 'package:sandbox/stories/alien_zone/spaceship_game.dart';
import 'package:sandbox/stories/alien_zone/spaceship_rail_game.dart';
import 'package:sandbox/stories/alien_zone/spaceship_ramp_game.dart';
void addAlienZoneStories(Dashbook dashbook) { void addAlienZoneStories(Dashbook dashbook) {
dashbook.storiesOf('Alien Zone') dashbook.storiesOf('Alien Zone')
..add( ..addGame(
'Alien Bumper A', title: 'Alien Bumper A',
(context) => GameWidget( description: AlienBumperAGame.description,
game: AlienBumperAGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => AlienBumperAGame(),
),
codeLink: buildSourceLink('alien_zone/alien_bumper_a.dart'),
info: AlienBumperAGame.info,
) )
..add( ..addGame(
'Alien Bumper B', title: 'Alien Bumper B',
(context) => GameWidget( description: AlienBumperBGame.description,
game: AlienBumperBGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => AlienBumperBGame(),
), )
codeLink: buildSourceLink('alien_zone/alien_bumper_b.dart'), ..addGame(
info: AlienBumperAGame.info, title: 'Spaceship',
description: SpaceshipGame.description,
gameBuilder: (_) => SpaceshipGame(),
)
..addGame(
title: 'Spaceship Rail',
description: SpaceshipRailGame.description,
gameBuilder: (_) => SpaceshipRailGame(),
)
..addGame(
title: 'Spaceship Ramp',
description: SpaceshipRampGame.description,
gameBuilder: (_) => SpaceshipRampGame(),
); );
} }

@ -1,21 +1,22 @@
import 'package:flame/components.dart'; import 'package:flame/input.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets; import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_theme/pinball_theme.dart'; import 'package:pinball_theme/pinball_theme.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BackboardGameOverGame extends BasicKeyboardGame { class BackboardGameOverGame extends AssetsGame
BackboardGameOverGame(this.score, this.character); with HasKeyboardHandlerComponents {
BackboardGameOverGame(this.score, this.character)
: super(
imagesFileNames: characterIconPaths.values.toList(),
);
static const info = ''' static const description = '''
Simple example showing the game over mode of the backboard. Shows how the Backboard in game over mode is rendered.
- Select a character to update the character icon. - Select a character to update the character icon.
'''; ''';
final int score;
final String character;
static final characterIconPaths = <String, String>{ static final characterIconPaths = <String, String>{
'Dash': Assets.images.dash.leaderboardIcon.keyName, 'Dash': Assets.images.dash.leaderboardIcon.keyName,
'Sparky': Assets.images.sparky.leaderboardIcon.keyName, 'Sparky': Assets.images.sparky.leaderboardIcon.keyName,
@ -23,14 +24,16 @@ class BackboardGameOverGame extends BasicKeyboardGame {
'Dino': Assets.images.dino.leaderboardIcon.keyName, 'Dino': Assets.images.dino.leaderboardIcon.keyName,
}; };
final int score;
final String character;
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
camera camera
..followVector2(Vector2.zero()) ..followVector2(Vector2.zero())
..zoom = 5; ..zoom = 5;
await images.loadAll(characterIconPaths.values.toList());
await add( await add(
Backboard.gameOver( Backboard.gameOver(
position: Vector2(0, 20), position: Vector2(0, 20),

@ -2,9 +2,14 @@ import 'package:flame/components.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BackboardWaitingGame extends BasicGame { class BackboardWaitingGame extends AssetsGame {
static const info = ''' BackboardWaitingGame()
Simple example showing the waiting mode of the backboard. : super(
imagesFileNames: [],
);
static const description = '''
Shows how the Backboard in waiting mode is rendered.
'''; ''';
@override @override
@ -13,7 +18,8 @@ class BackboardWaitingGame extends BasicGame {
..followVector2(Vector2.zero()) ..followVector2(Vector2.zero())
..zoom = 5; ..zoom = 5;
final backboard = Backboard.waiting(position: Vector2(0, 20)); await add(
await add(backboard); Backboard.waiting(position: Vector2(0, 20)),
);
} }
} }

@ -1,23 +1,19 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/backboard/backboard_game_over_game.dart'; import 'package:sandbox/stories/backboard/backboard_game_over_game.dart';
import 'package:sandbox/stories/backboard/backboard_waiting_game.dart'; import 'package:sandbox/stories/backboard/backboard_waiting_game.dart';
void addBackboardStories(Dashbook dashbook) { void addBackboardStories(Dashbook dashbook) {
dashbook.storiesOf('Backboard') dashbook.storiesOf('Backboard')
..add( ..addGame(
'Waiting mode', title: 'Waiting',
(context) => GameWidget( description: BackboardWaitingGame.description,
game: BackboardWaitingGame(), gameBuilder: (_) => BackboardWaitingGame(),
),
codeLink: buildSourceLink('backboard/waiting.dart'),
info: BackboardWaitingGame.info,
) )
..add( ..addGame(
'Game over', title: 'Game over',
(context) => GameWidget( description: BackboardGameOverGame.description,
game: BackboardGameOverGame( gameBuilder: (context) => BackboardGameOverGame(
context.numberProperty('Score', 9000000000).toInt(), context.numberProperty('Score', 9000000000).toInt(),
context.listProperty( context.listProperty(
'Character', 'Character',
@ -25,8 +21,5 @@ void addBackboardStories(Dashbook dashbook) {
BackboardGameOverGame.characterIconPaths.keys.toList(), BackboardGameOverGame.characterIconPaths.keys.toList(),
), ),
), ),
),
codeLink: buildSourceLink('backboard/game_over.dart'),
info: BackboardGameOverGame.info,
); );
} }

@ -4,7 +4,7 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BallBoosterGame extends LineGame { class BallBoosterGame extends LineGame {
static const info = ''' static const description = '''
Shows how a Ball with a boost works. Shows how a Ball with a boost works.
- Drag to launch a boosted Ball. - Drag to launch a boosted Ball.

@ -3,14 +3,20 @@ import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BasicBallGame extends BasicGame with TapDetector, Traceable { class BallGame extends AssetsGame with TapDetector, Traceable {
BasicBallGame({ BallGame({
this.color = Colors.blue, this.color = Colors.blue,
this.ballPriority = 0, this.ballPriority = 0,
this.ballLayer = Layer.all, this.ballLayer = Layer.all,
}); List<String>? imagesFileNames,
}) : super(
imagesFileNames: [
Assets.images.ball.ball.keyName,
if (imagesFileNames != null) ...imagesFileNames,
],
);
static const info = ''' static const description = '''
Shows how a Ball works. Shows how a Ball works.
- Tap anywhere on the screen to spawn a ball into the game. - Tap anywhere on the screen to spawn a ball into the game.

@ -1,5 +1,4 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/ball_booster_game.dart'; import 'package:sandbox/stories/ball/ball_booster_game.dart';
@ -7,22 +6,16 @@ import 'package:sandbox/stories/ball/basic_ball_game.dart';
void addBallStories(Dashbook dashbook) { void addBallStories(Dashbook dashbook) {
dashbook.storiesOf('Ball') dashbook.storiesOf('Ball')
..add( ..addGame(
'Basic', title: 'Colored',
(context) => GameWidget( description: BallGame.description,
game: BasicBallGame( gameBuilder: (context) => BallGame(
color: context.colorProperty('color', Colors.blue), color: context.colorProperty('color', Colors.blue),
)..trace = context.boolProperty('Trace', true),
), ),
codeLink: buildSourceLink('ball/basic.dart'),
info: BasicBallGame.info,
) )
..add( ..addGame(
'Booster', title: 'Booster',
(context) => GameWidget( description: BallBoosterGame.description,
game: BallBoosterGame(), gameBuilder: (context) => BallBoosterGame(),
),
codeLink: buildSourceLink('ball/ball_booster.dart'),
info: BallBoosterGame.info,
); );
} }

@ -1,10 +1,17 @@
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class BaseboardGame extends BasicBallGame with Traceable { class BaseboardGame extends BallGame {
static const info = ''' BaseboardGame()
: super(
imagesFileNames: [
Assets.images.baseboard.left.keyName,
Assets.images.baseboard.right.keyName,
],
);
static const description = '''
Shows how the Baseboards are rendered. Shows how the Baseboards are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -15,22 +22,14 @@ class BaseboardGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.baseboard.left.keyName,
Assets.images.baseboard.right.keyName,
]);
final center = screenToWorld(camera.viewport.canvasSize! / 2); final center = screenToWorld(camera.viewport.canvasSize! / 2);
final leftBaseboard = Baseboard(side: BoardSide.left) await addAll([
Baseboard(side: BoardSide.left)
..initialPosition = center - Vector2(25, 0) ..initialPosition = center - Vector2(25, 0)
..priority = 1; ..priority = 1,
final rightBaseboard = Baseboard(side: BoardSide.right) Baseboard(side: BoardSide.right)
..initialPosition = center + Vector2(25, 0) ..initialPosition = center + Vector2(25, 0)
..priority = 1; ..priority = 1,
await addAll([
leftBaseboard,
rightBaseboard,
]); ]);
await traceAllBodies(); await traceAllBodies();

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/baseboard/baseboard_game.dart'; import 'package:sandbox/stories/baseboard/baseboard_game.dart';
void addBaseboardStories(Dashbook dashbook) { void addBaseboardStories(Dashbook dashbook) {
dashbook.storiesOf('Baseboard').add( dashbook.storiesOf('Baseboard').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: BaseboardGame.description,
game: BaseboardGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => BaseboardGame(),
),
codeLink: buildSourceLink('baseboard_game/basic.dart'),
info: BaseboardGame.info,
); );
} }

@ -1,11 +1,19 @@
import 'package:flame/extensions.dart'; import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class BoundariesGame extends BasicBallGame with Traceable { class BoundariesGame extends BallGame {
static const info = ''' BoundariesGame()
: super(
imagesFileNames: [
Assets.images.boundary.outer.keyName,
Assets.images.boundary.outerBottom.keyName,
Assets.images.boundary.bottom.keyName,
],
);
static const description = '''
Shows how Boundaries are rendered. Shows how Boundaries are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,18 +24,11 @@ class BoundariesGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.boundary.outer.keyName,
Assets.images.boundary.bottom.keyName,
]);
await addFromBlueprint(Boundaries());
await ready();
camera camera
..followVector2(Vector2.zero()) ..followVector2(Vector2.zero())
..zoom = 6; ..zoom = 6;
await addFromBlueprint(Boundaries());
await ready();
await traceAllBodies(); await traceAllBodies();
} }
} }

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/boundaries/boundaries_game.dart'; import 'package:sandbox/stories/boundaries/boundaries_game.dart';
void addBoundariesStories(Dashbook dashbook) { void addBoundariesStories(Dashbook dashbook) {
dashbook.storiesOf('Boundaries').add( dashbook.storiesOf('Boundaries').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: BoundariesGame.description,
game: BoundariesGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => BoundariesGame(),
),
codeLink: buildSourceLink('boundaries_game/basic.dart'),
info: BoundariesGame.info,
); );
} }

@ -2,7 +2,7 @@ import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
class ChromeDinoGame extends Forge2DGame { class ChromeDinoGame extends Forge2DGame {
static const info = 'Shows how a ChromeDino is rendered.'; static const description = 'Shows how a ChromeDino is rendered.';
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/chrome_dino/chrome_dino_game.dart'; import 'package:sandbox/stories/chrome_dino/chrome_dino_game.dart';
void addChromeDinoStories(Dashbook dashbook) { void addChromeDinoStories(Dashbook dashbook) {
dashbook.storiesOf('Chrome Dino').add( dashbook.storiesOf('Chrome Dino').addGame(
'Basic', title: 'Trace',
(context) => GameWidget( description: ChromeDinoGame.description,
game: ChromeDinoGame(), gameBuilder: (_) => ChromeDinoGame(),
),
codeLink: buildSourceLink('chrome_dino/basic.dart'),
info: ChromeDinoGame.info,
); );
} }

@ -3,8 +3,8 @@ import 'package:flame/input.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class BasicCameraZoomGame extends BasicGame with TapDetector { class CameraZoomGame extends AssetsGame with TapDetector {
static const info = ''' static const description = '''
Shows how CameraZoom can be used. Shows how CameraZoom can be used.
- Tap to zoom in/out. - Tap to zoom in/out.

@ -3,7 +3,7 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class FireEffectGame extends LineGame { class FireEffectGame extends LineGame {
static const info = ''' static const description = '''
Shows how the FireEffect renders. Shows how the FireEffect renders.
- Drag a line to define the trail direction. - Drag a line to define the trail direction.

@ -1,13 +1,18 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/effects/camera_zoom_game.dart';
import 'package:sandbox/stories/effects/fire_effect_game.dart'; import 'package:sandbox/stories/effects/fire_effect_game.dart';
void addEffectsStories(Dashbook dashbook) { void addEffectsStories(Dashbook dashbook) {
dashbook.storiesOf('Effects').add( dashbook.storiesOf('Effects')
'Fire Effect', ..addGame(
(context) => GameWidget(game: FireEffectGame()), title: 'Fire',
codeLink: buildSourceLink('effects/fire_effect.dart'), description: FireEffectGame.description,
info: FireEffectGame.info, gameBuilder: (_) => FireEffectGame(),
)
..addGame(
title: 'CameraZoom',
description: CameraZoomGame.description,
gameBuilder: (_) => CameraZoomGame(),
); );
} }

@ -2,12 +2,19 @@ import 'package:flame/input.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class FlipperGame extends BasicBallGame with KeyboardEvents, Traceable { class FlipperGame extends BallGame with KeyboardEvents {
static const info = ''' FlipperGame()
: super(
imagesFileNames: [
Assets.images.flipper.left.keyName,
Assets.images.flipper.right.keyName,
],
);
static const description = '''
Shows how Flippers are rendered. Shows how Flippers are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -33,21 +40,12 @@ class FlipperGame extends BasicBallGame with KeyboardEvents, Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.flipper.left.keyName,
Assets.images.flipper.right.keyName,
]);
final center = screenToWorld(camera.viewport.canvasSize! / 2); final center = screenToWorld(camera.viewport.canvasSize! / 2);
await addAll([
leftFlipper = Flipper(side: BoardSide.left) leftFlipper = Flipper(side: BoardSide.left)
..initialPosition = center - Vector2(Flipper.size.x, 0); ..initialPosition = center - Vector2(Flipper.size.x, 0),
rightFlipper = Flipper(side: BoardSide.right) rightFlipper = Flipper(side: BoardSide.right)
..initialPosition = center + Vector2(Flipper.size.x, 0); ..initialPosition = center + Vector2(Flipper.size.x, 0),
await addAll([
leftFlipper,
rightFlipper,
]); ]);
await traceAllBodies(); await traceAllBodies();

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/flipper/flipper_game.dart'; import 'package:sandbox/stories/flipper/flipper_game.dart';
void addFlipperStories(Dashbook dashbook) { void addFlipperStories(Dashbook dashbook) {
dashbook.storiesOf('Flipper').add( dashbook.storiesOf('Flipper').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: FlipperGame.description,
game: FlipperGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => FlipperGame(),
),
codeLink: buildSourceLink('flipper/basic.dart'),
info: FlipperGame.info,
); );
} }

@ -2,11 +2,18 @@ import 'dart:async';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class BigDashNestBumperGame extends BasicBallGame with Traceable { class BigDashNestBumperGame extends BallGame {
static const info = ''' BigDashNestBumperGame()
: super(
imagesFileNames: [
Assets.images.dash.bumper.main.active.keyName,
Assets.images.dash.bumper.main.inactive.keyName,
],
);
static const description = '''
Shows how a BigDashNestBumper is rendered. Shows how a BigDashNestBumper is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,13 +23,10 @@ class BigDashNestBumperGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.dash.bumper.main.active.keyName,
Assets.images.dash.bumper.main.inactive.keyName,
]);
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await add(DashNestBumper.main()..priority = 1); await add(
DashNestBumper.main()..priority = 1,
);
await traceAllBodies(); await traceAllBodies();
} }
} }

@ -2,11 +2,20 @@ import 'dart:async';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SignpostGame extends BasicBallGame with Traceable, TapDetector { class SignpostGame extends BallGame {
static const info = ''' SignpostGame()
: super(
imagesFileNames: [
Assets.images.signpost.inactive.keyName,
Assets.images.signpost.active1.keyName,
Assets.images.signpost.active2.keyName,
Assets.images.signpost.active3.keyName,
],
);
static const description = '''
Shows how a Signpost is rendered. Shows how a Signpost is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -17,13 +26,6 @@ class SignpostGame extends BasicBallGame with Traceable, TapDetector {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.signpost.inactive.keyName,
Assets.images.signpost.active1.keyName,
Assets.images.signpost.active2.keyName,
Assets.images.signpost.active3.keyName,
]);
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await add(Signpost()); await add(Signpost());
await traceAllBodies(); await traceAllBodies();

@ -2,11 +2,18 @@ import 'dart:async';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SmallDashNestBumperAGame extends BasicBallGame with Traceable { class SmallDashNestBumperAGame extends BallGame {
static const info = ''' SmallDashNestBumperAGame()
: super(
imagesFileNames: [
Assets.images.dash.bumper.a.active.keyName,
Assets.images.dash.bumper.a.inactive.keyName,
],
);
static const description = '''
Shows how a SmallDashNestBumper ("a") is rendered. Shows how a SmallDashNestBumper ("a") is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,11 +23,6 @@ class SmallDashNestBumperAGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.dash.bumper.a.active.keyName,
Assets.images.dash.bumper.a.inactive.keyName,
]);
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await add(DashNestBumper.a()..priority = 1); await add(DashNestBumper.a()..priority = 1);
await traceAllBodies(); await traceAllBodies();

@ -2,11 +2,18 @@ import 'dart:async';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SmallDashNestBumperBGame extends BasicBallGame with Traceable { class SmallDashNestBumperBGame extends BallGame {
static const info = ''' SmallDashNestBumperBGame()
: super(
imagesFileNames: [
Assets.images.dash.bumper.b.active.keyName,
Assets.images.dash.bumper.b.inactive.keyName,
],
);
static const description = '''
Shows how a SmallDashNestBumper ("b") is rendered. Shows how a SmallDashNestBumper ("b") is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,11 +23,6 @@ class SmallDashNestBumperBGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.dash.bumper.b.active.keyName,
Assets.images.dash.bumper.b.inactive.keyName,
]);
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await add(DashNestBumper.b()..priority = 1); await add(DashNestBumper.b()..priority = 1);
await traceAllBodies(); await traceAllBodies();

@ -1,5 +1,4 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/flutter_forest/big_dash_nest_bumper_game.dart'; import 'package:sandbox/stories/flutter_forest/big_dash_nest_bumper_game.dart';
import 'package:sandbox/stories/flutter_forest/signpost_game.dart'; import 'package:sandbox/stories/flutter_forest/signpost_game.dart';
@ -8,39 +7,24 @@ import 'package:sandbox/stories/flutter_forest/small_dash_nest_bumper_b_game.dar
void addDashNestBumperStories(Dashbook dashbook) { void addDashNestBumperStories(Dashbook dashbook) {
dashbook.storiesOf('Flutter Forest') dashbook.storiesOf('Flutter Forest')
..add( ..addGame(
'Signpost', title: 'Signpost',
(context) => GameWidget( description: SignpostGame.description,
game: SignpostGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => SignpostGame(),
),
codeLink: buildSourceLink('flutter_forest/signpost.dart'),
info: SignpostGame.info,
) )
..add( ..addGame(
'Big Dash Nest Bumper', title: 'Big Dash Nest Bumper',
(context) => GameWidget( description: BigDashNestBumperGame.description,
game: BigDashNestBumperGame() gameBuilder: (_) => BigDashNestBumperGame(),
..trace = context.boolProperty('Trace', true),
),
codeLink: buildSourceLink('flutter_forest/big_dash_nest_bumper.dart'),
info: BigDashNestBumperGame.info,
) )
..add( ..addGame(
'Small Dash Nest Bumper A', title: 'Small Dash Nest Bumper A',
(context) => GameWidget( description: SmallDashNestBumperAGame.description,
game: SmallDashNestBumperAGame() gameBuilder: (_) => SmallDashNestBumperAGame(),
..trace = context.boolProperty('Trace', true),
),
codeLink: buildSourceLink('flutter_forest/small_dash_nest_bumper_a.dart'),
info: SmallDashNestBumperAGame.info,
) )
..add( ..addGame(
'Small Dash Nest Bumper B', title: 'Small Dash Nest Bumper B',
(context) => GameWidget( description: SmallDashNestBumperBGame.description,
game: SmallDashNestBumperBGame() gameBuilder: (_) => SmallDashNestBumperBGame(),
..trace = context.boolProperty('Trace', true),
),
codeLink: buildSourceLink('flutter_forest/small_dash_nest_bumper_b.dart'),
info: SmallDashNestBumperBGame.info,
); );
} }

@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class GoogleLetterGame extends BasicBallGame { class GoogleLetterGame extends BallGame {
GoogleLetterGame() : super(color: const Color(0xFF009900)); GoogleLetterGame() : super(color: const Color(0xFF009900));
static const info = ''' static const description = '''
Shows how a GoogleLetter is rendered. Shows how a GoogleLetter is rendered.
- Tap anywhere on the screen to spawn a ball into the game. - Tap anywhere on the screen to spawn a ball into the game.

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/google_word/google_letter_game.dart'; import 'package:sandbox/stories/google_word/google_letter_game.dart';
void addGoogleWordStories(Dashbook dashbook) { void addGoogleWordStories(Dashbook dashbook) {
dashbook.storiesOf('Google Word').add( dashbook.storiesOf('Google Word').addGame(
'Letter', title: 'Letter 0',
(context) => GameWidget( description: GoogleLetterGame.description,
game: GoogleLetterGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => GoogleLetterGame(),
),
codeLink: buildSourceLink('google_word/letter.dart'),
info: GoogleLetterGame.info,
); );
} }

@ -1,10 +1,9 @@
import 'package:flame/extensions.dart'; import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class KickerGame extends BasicBallGame with Traceable { class KickerGame extends BallGame {
static const info = ''' static const description = '''
Shows how Kickers are rendered. Shows how Kickers are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,14 +15,14 @@ class KickerGame extends BasicBallGame with Traceable {
await super.onLoad(); await super.onLoad();
final center = screenToWorld(camera.viewport.canvasSize! / 2); final center = screenToWorld(camera.viewport.canvasSize! / 2);
await addAll(
final leftKicker = Kicker(side: BoardSide.left) [
..initialPosition = Vector2(center.x - (Kicker.size.x * 2), center.y); Kicker(side: BoardSide.left)
await add(leftKicker); ..initialPosition = Vector2(center.x - (Kicker.size.x * 2), center.y),
Kicker(side: BoardSide.right)
final rightKicker = Kicker(side: BoardSide.right) ..initialPosition = Vector2(center.x + (Kicker.size.x * 2), center.y),
..initialPosition = Vector2(center.x + (Kicker.size.x * 2), center.y); ],
await add(rightKicker); );
await traceAllBodies(); await traceAllBodies();
} }

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/kicker/kicker_game.dart'; import 'package:sandbox/stories/kicker/kicker_game.dart';
void addKickerStories(Dashbook dashbook) { void addKickerStories(Dashbook dashbook) {
dashbook.storiesOf('Kickers').add( dashbook.storiesOf('Kickers').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: KickerGame.description,
game: KickerGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => KickerGame(),
),
codeLink: buildSourceLink('kicker_game/basic.dart'),
info: KickerGame.info,
); );
} }

@ -6,7 +6,7 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class LaunchRampGame extends BasicBallGame { class LaunchRampGame extends BallGame {
LaunchRampGame() LaunchRampGame()
: super( : super(
color: Colors.blue, color: Colors.blue,
@ -14,7 +14,7 @@ class LaunchRampGame extends BasicBallGame {
ballLayer: Layer.launcher, ballLayer: Layer.launcher,
); );
static const info = ''' static const description = '''
Shows how LaunchRamp are rendered. Shows how LaunchRamp are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -28,10 +28,8 @@ class LaunchRampGame extends BasicBallGame {
camera camera
..followVector2(Vector2(0, 0)) ..followVector2(Vector2(0, 0))
..zoom = 7.5; ..zoom = 7.5;
await addFromBlueprint(LaunchRamp());
final launchRamp = LaunchRamp(); await ready();
unawaited(addFromBlueprint(launchRamp));
await traceAllBodies(); await traceAllBodies();
} }
} }

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/launch_ramp/launch_ramp_game.dart'; import 'package:sandbox/stories/launch_ramp/launch_ramp_game.dart';
void addLaunchRampStories(Dashbook dashbook) { void addLaunchRampStories(Dashbook dashbook) {
dashbook.storiesOf('LaunchRamp').add( dashbook.storiesOf('LaunchRamp').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: LaunchRampGame.description,
game: LaunchRampGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => LaunchRampGame(),
),
codeLink: buildSourceLink('launch_ramp/basic.dart'),
info: LaunchRampGame.info,
); );
} }

@ -2,36 +2,35 @@ import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class BasicLayerGame extends BasicGame with TapDetector { class LayerGame extends BallGame with TapDetector {
BasicLayerGame({required this.color}); static const description = '''
static const info = '''
Shows how Layers work when a Ball hits other components. Shows how Layers work when a Ball hits other components.
- Tap anywhere on the screen to spawn a Ball into the game. - Tap anywhere on the screen to spawn a Ball into the game.
'''; ''';
final Color color;
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
await add(BigSquare()..initialPosition = Vector2(30, -40)); await addAll(
await add(SmallSquare()..initialPosition = Vector2(50, -40)); [
await add(UnlayeredSquare()..initialPosition = Vector2(60, -40)); _BigSquare()..initialPosition = Vector2(30, -40),
} _SmallSquare()..initialPosition = Vector2(50, -40),
_UnlayeredSquare()..initialPosition = Vector2(60, -40),
@override ],
void onTapUp(TapUpInfo info) {
add(
Ball(baseColor: color)..initialPosition = info.eventPosition.game,
); );
} }
} }
class BigSquare extends BodyComponent with InitialPosition, Layered { class _BigSquare extends BodyComponent with InitialPosition, Layered {
BigSquare() { _BigSquare()
: super(
children: [
_UnlayeredSquare()..initialPosition = Vector2.all(4),
_SmallSquare()..initialPosition = Vector2.all(-4),
],
) {
paint = Paint() paint = Paint()
..color = const Color.fromARGB(255, 8, 218, 241) ..color = const Color.fromARGB(255, 8, 218, 241)
..style = PaintingStyle.stroke; ..style = PaintingStyle.stroke;
@ -42,27 +41,13 @@ class BigSquare extends BodyComponent with InitialPosition, Layered {
Body createBody() { Body createBody() {
final shape = PolygonShape()..setAsBoxXY(16, 16); final shape = PolygonShape()..setAsBoxXY(16, 16);
final fixtureDef = FixtureDef(shape); final fixtureDef = FixtureDef(shape);
final bodyDef = BodyDef()..position = initialPosition; final bodyDef = BodyDef()..position = initialPosition;
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixture(fixtureDef);
} }
@override
Future<void> onLoad() async {
await super.onLoad();
await addAll(
[
UnlayeredSquare()..initialPosition = Vector2.all(4),
SmallSquare()..initialPosition = Vector2.all(-4),
],
);
}
} }
class SmallSquare extends BodyComponent with InitialPosition, Layered { class _SmallSquare extends BodyComponent with InitialPosition, Layered {
SmallSquare() { _SmallSquare() {
paint = Paint() paint = Paint()
..color = const Color.fromARGB(255, 27, 241, 8) ..color = const Color.fromARGB(255, 27, 241, 8)
..style = PaintingStyle.stroke; ..style = PaintingStyle.stroke;
@ -73,15 +58,13 @@ class SmallSquare extends BodyComponent with InitialPosition, Layered {
Body createBody() { Body createBody() {
final shape = PolygonShape()..setAsBoxXY(2, 2); final shape = PolygonShape()..setAsBoxXY(2, 2);
final fixtureDef = FixtureDef(shape); final fixtureDef = FixtureDef(shape);
final bodyDef = BodyDef()..position = initialPosition; final bodyDef = BodyDef()..position = initialPosition;
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixture(fixtureDef);
} }
} }
class UnlayeredSquare extends BodyComponent with InitialPosition { class _UnlayeredSquare extends BodyComponent with InitialPosition {
UnlayeredSquare() { _UnlayeredSquare() {
paint = Paint() paint = Paint()
..color = const Color.fromARGB(255, 241, 8, 8) ..color = const Color.fromARGB(255, 241, 8, 8)
..style = PaintingStyle.stroke; ..style = PaintingStyle.stroke;
@ -91,9 +74,7 @@ class UnlayeredSquare extends BodyComponent with InitialPosition {
Body createBody() { Body createBody() {
final shape = PolygonShape()..setAsBoxXY(3, 3); final shape = PolygonShape()..setAsBoxXY(3, 3);
final fixtureDef = FixtureDef(shape); final fixtureDef = FixtureDef(shape);
final bodyDef = BodyDef()..position = initialPosition; final bodyDef = BodyDef()..position = initialPosition;
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixture(fixtureDef);
} }
} }

@ -1,18 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/layer/basic_layer_game.dart'; import 'package:sandbox/stories/layer/layer_game.dart';
void addLayerStories(Dashbook dashbook) { void addLayerStories(Dashbook dashbook) {
dashbook.storiesOf('Layer').add( dashbook.storiesOf('Layer').addGame(
'Layer', title: 'Example',
(context) => GameWidget( description: LayerGame.description,
game: BasicLayerGame( gameBuilder: (_) => LayerGame(),
color: context.colorProperty('color', Colors.blue),
),
),
codeLink: buildSourceLink('layer/basic.dart'),
info: BasicLayerGame.info,
); );
} }

@ -5,10 +5,10 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class PlungerGame extends BasicBallGame with KeyboardEvents, Traceable { class PlungerGame extends BallGame with KeyboardEvents, Traceable {
PlungerGame() : super(color: const Color(0xFFFF0000)); PlungerGame() : super(color: const Color(0xFFFF0000));
static const info = ''' static const description = '''
Shows how Plunger is rendered. Shows how Plunger is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -27,11 +27,10 @@ class PlungerGame extends BasicBallGame with KeyboardEvents, Traceable {
await super.onLoad(); await super.onLoad();
final center = screenToWorld(camera.viewport.canvasSize! / 2); final center = screenToWorld(camera.viewport.canvasSize! / 2);
await add(
plunger = Plunger(compressionDistance: 29) plunger = Plunger(compressionDistance: 29)
..initialPosition = Vector2(center.x - (Kicker.size.x * 2), center.y); ..initialPosition = Vector2(center.x - (Kicker.size.x * 2), center.y),
await add(plunger); );
await traceAllBodies(); await traceAllBodies();
} }

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/plunger/plunger_game.dart'; import 'package:sandbox/stories/plunger/plunger_game.dart';
void addPlungerStories(Dashbook dashbook) { void addPlungerStories(Dashbook dashbook) {
dashbook.storiesOf('Plunger').add( dashbook.storiesOf('Plunger').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: PlungerGame.description,
game: PlungerGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => PlungerGame(),
),
codeLink: buildSourceLink('plunger_game/basic.dart'),
info: PlungerGame.info,
); );
} }

@ -5,8 +5,8 @@ import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
class ScoreTextBasicGame extends BasicGame with TapDetector { class ScoreTextGame extends AssetsGame with TapDetector {
static const info = ''' static const description = '''
Simple game to show how score text works, Simple game to show how score text works,
- Tap anywhere on the screen to spawn an text on the given location. - Tap anywhere on the screen to spawn an text on the given location.

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/score_text/basic.dart'; import 'package:sandbox/stories/score_text/score_text_game.dart';
void addScoreTextStories(Dashbook dashbook) { void addScoreTextStories(Dashbook dashbook) {
dashbook.storiesOf('ScoreText').add( dashbook.storiesOf('ScoreText').addGame(
'Basic', title: 'Basic',
(context) => GameWidget( description: ScoreTextGame.description,
game: ScoreTextBasicGame(), gameBuilder: (_) => ScoreTextGame(),
),
codeLink: buildSourceLink('score_text/basic.dart'),
info: ScoreTextBasicGame.info,
); );
} }

@ -1,11 +1,18 @@
import 'package:flame/extensions.dart'; import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SlingshotGame extends BasicBallGame with Traceable { class SlingshotGame extends BallGame {
static const info = ''' SlingshotGame()
: super(
imagesFileNames: [
Assets.images.slingshot.upper.keyName,
Assets.images.slingshot.lower.keyName,
],
);
static const description = '''
Shows how Slingshots are rendered. Shows how Slingshots are rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.
@ -16,13 +23,9 @@ class SlingshotGame extends BasicBallGame with Traceable {
Future<void> onLoad() async { Future<void> onLoad() async {
await super.onLoad(); await super.onLoad();
await images.loadAll([
Assets.images.slingshot.upper.keyName,
Assets.images.slingshot.lower.keyName,
]);
await addFromBlueprint(Slingshots());
camera.followVector2(Vector2.zero()); camera.followVector2(Vector2.zero());
await addFromBlueprint(Slingshots());
await ready();
await traceAllBodies(); await traceAllBodies();
} }
} }

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/slingshot/slingshot_game.dart'; import 'package:sandbox/stories/slingshot/slingshot_game.dart';
void addSlingshotStories(Dashbook dashbook) { void addSlingshotStories(Dashbook dashbook) {
dashbook.storiesOf('Slingshots').add( dashbook.storiesOf('Slingshots').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: SlingshotGame.description,
game: SlingshotGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => SlingshotGame(),
),
codeLink: buildSourceLink('slingshot_game/basic.dart'),
info: SlingshotGame.info,
); );
} }

@ -1,15 +0,0 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/spaceship/basic_spaceship_game.dart';
void addSpaceshipStories(Dashbook dashbook) {
dashbook.storiesOf('Spaceship').add(
'Basic',
(context) => GameWidget(
game: BasicSpaceshipGame(),
),
codeLink: buildSourceLink('spaceship/basic.dart'),
info: BasicSpaceshipGame.info,
);
}

@ -1,16 +0,0 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/spaceship_rail/spaceship_rail_game.dart';
void addSpaceshipRailStories(Dashbook dashbook) {
dashbook.storiesOf('SpaceshipRail').add(
'Basic',
(context) => GameWidget(
game: SpaceshipRailGame()
..trace = context.boolProperty('Trace', true),
),
codeLink: buildSourceLink('spaceship_rail/basic.dart'),
info: SpaceshipRailGame.info,
);
}

@ -1,16 +0,0 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/spaceship_ramp/spaceship_ramp_game.dart';
void addSpaceshipRampStories(Dashbook dashbook) {
dashbook.storiesOf('SpaceshipRamp').add(
'Basic',
(context) => GameWidget(
game: SpaceshipRampGame()
..trace = context.boolProperty('Trace', true),
),
codeLink: buildSourceLink('spaceship_ramp/basic.dart'),
info: SpaceshipRampGame.info,
);
}

@ -2,11 +2,10 @@ import 'dart:async';
import 'package:flame/extensions.dart'; import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart'; import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SparkyBumperGame extends BasicBallGame with Traceable { class SparkyBumperGame extends BallGame {
static const info = ''' static const description = '''
Shows how a SparkyBumper is rendered. Shows how a SparkyBumper is rendered.
- Activate the "trace" parameter to overlay the body. - Activate the "trace" parameter to overlay the body.

@ -1,15 +1,11 @@
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart'; import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/sparky_bumper/sparky_bumper_game.dart'; import 'package:sandbox/stories/sparky_bumper/sparky_bumper_game.dart';
void addSparkyBumperStories(Dashbook dashbook) { void addSparkyBumperStories(Dashbook dashbook) {
dashbook.storiesOf('Sparky Bumpers').add( dashbook.storiesOf('Sparky Bumpers').addGame(
'Basic', title: 'Traced',
(context) => GameWidget( description: SparkyBumperGame.description,
game: SparkyBumperGame()..trace = context.boolProperty('Trace', true), gameBuilder: (_) => SparkyBumperGame(),
),
codeLink: buildSourceLink('sparky_bumper/basic.dart'),
info: SparkyBumperGame.info,
); );
} }

@ -13,8 +13,4 @@ export 'layer/stories.dart';
export 'plunger/stories.dart'; export 'plunger/stories.dart';
export 'score_text/stories.dart'; export 'score_text/stories.dart';
export 'slingshot/stories.dart'; export 'slingshot/stories.dart';
export 'spaceship/stories.dart';
export 'spaceship_rail/stories.dart';
export 'spaceship_ramp/stories.dart';
export 'sparky_bumper/stories.dart'; export 'sparky_bumper/stories.dart';
export 'zoom/stories.dart';

@ -1,15 +0,0 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/zoom/basic_zoom_game.dart';
void addZoomStories(Dashbook dashbook) {
dashbook.storiesOf('CameraZoom').add(
'Basic',
(context) => GameWidget(
game: BasicCameraZoomGame(),
),
codeLink: buildSourceLink('zoom/basic_zoom_game.dart'),
info: BasicCameraZoomGame.info,
);
}

@ -10,20 +10,24 @@ import '../../helpers/helpers.dart';
void main() { void main() {
group('Boundaries', () { group('Boundaries', () {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [ final assets = [
Assets.images.boundary.outer.keyName, Assets.images.boundary.outer.keyName,
Assets.images.boundary.outerBottom.keyName,
Assets.images.boundary.bottom.keyName, Assets.images.boundary.bottom.keyName,
]; ];
final tester = FlameTester(TestGame.new); final flameTester = FlameTester(TestGame.new);
tester.testGameWidget( flameTester.testGameWidget(
'render correctly', 'render correctly',
setUp: (game, tester) async { setUp: (game, tester) async {
await game.images.loadAll(assets); await game.images.loadAll(assets);
await game.addFromBlueprint(Boundaries()); await game.addFromBlueprint(Boundaries());
await game.ready();
game.camera.followVector2(Vector2.zero()); game.camera.followVector2(Vector2.zero());
game.camera.zoom = 3.2; game.camera.zoom = 3.2;
await tester.pump();
}, },
verify: (game, tester) async { verify: (game, tester) async {
await expectLater( await expectLater(

@ -22,7 +22,9 @@ void main() {
await tester.pump(); await tester.pump();
}, },
verify: (game, tester) async { verify: (game, tester) async {
const animationDuration = 3.25; final animationDuration =
game.firstChild<DashAnimatronic>()!.animation!.totalDuration();
await expectLater( await expectLater(
find.byGame<TestGame>(), find.byGame<TestGame>(),
matchesGoldenFile('golden/dash_animatronic/start.png'), matchesGoldenFile('golden/dash_animatronic/start.png'),
@ -60,8 +62,7 @@ void main() {
await game.ensureAdd(dashAnimatronic); await game.ensureAdd(dashAnimatronic);
dashAnimatronic.playing = true; dashAnimatronic.playing = true;
dashAnimatronic.animation?.setToLast(); game.update(4);
game.update(1);
expect(dashAnimatronic.playing, isFalse); expect(dashAnimatronic.playing, isFalse);
}, },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

@ -0,0 +1,76 @@
// ignore_for_file: cascade_invocations
import 'package:flame/extensions.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();
group('SparkyAnimatronic', () {
final asset = Assets.images.sparky.animatronic.keyName;
final flameTester = FlameTester(() => TestGame([asset]));
flameTester.testGameWidget(
'renders correctly',
setUp: (game, tester) async {
await game.images.load(asset);
await game.ensureAdd(SparkyAnimatronic()..playing = true);
await tester.pump();
game.camera.followVector2(Vector2.zero());
},
verify: (game, tester) async {
final animationDuration =
game.firstChild<SparkyAnimatronic>()!.animation!.totalDuration();
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/sparky_animatronic/start.png'),
);
game.update(animationDuration * 0.25);
await tester.pump();
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/sparky_animatronic/middle.png'),
);
game.update(animationDuration * 0.75);
await tester.pump();
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/sparky_animatronic/end.png'),
);
},
);
flameTester.test(
'loads correctly',
(game) async {
final sparkyAnimatronic = SparkyAnimatronic();
await game.ensureAdd(sparkyAnimatronic);
expect(game.contains(sparkyAnimatronic), isTrue);
},
);
flameTester.test(
'stops animating after animation completes',
(game) async {
final sparkyAnimatronic = SparkyAnimatronic();
await game.ensureAdd(sparkyAnimatronic);
sparkyAnimatronic.playing = true;
final animationDuration =
game.firstChild<SparkyAnimatronic>()!.animation!.totalDuration();
game.update(animationDuration);
expect(sparkyAnimatronic.playing, isFalse);
},
);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

@ -28,6 +28,10 @@ class $AssetsImagesGen {
class $AssetsImagesAndroidGen { class $AssetsImagesAndroidGen {
const $AssetsImagesAndroidGen(); const $AssetsImagesAndroidGen();
/// File path: assets/images/android/animation.png
AssetGenImage get animation =>
const AssetGenImage('assets/images/android/animation.png');
/// File path: assets/images/android/background.png /// File path: assets/images/android/background.png
AssetGenImage get background => AssetGenImage get background =>
const AssetGenImage('assets/images/android/background.png'); const AssetGenImage('assets/images/android/background.png');
@ -48,6 +52,10 @@ class $AssetsImagesAndroidGen {
class $AssetsImagesDashGen { class $AssetsImagesDashGen {
const $AssetsImagesDashGen(); const $AssetsImagesDashGen();
/// File path: assets/images/dash/animation.png
AssetGenImage get animation =>
const AssetGenImage('assets/images/dash/animation.png');
/// File path: assets/images/dash/background.png /// File path: assets/images/dash/background.png
AssetGenImage get background => AssetGenImage get background =>
const AssetGenImage('assets/images/dash/background.png'); const AssetGenImage('assets/images/dash/background.png');
@ -67,6 +75,10 @@ class $AssetsImagesDashGen {
class $AssetsImagesDinoGen { class $AssetsImagesDinoGen {
const $AssetsImagesDinoGen(); const $AssetsImagesDinoGen();
/// File path: assets/images/dino/animation.png
AssetGenImage get animation =>
const AssetGenImage('assets/images/dino/animation.png');
/// File path: assets/images/dino/background.png /// File path: assets/images/dino/background.png
AssetGenImage get background => AssetGenImage get background =>
const AssetGenImage('assets/images/dino/background.png'); const AssetGenImage('assets/images/dino/background.png');
@ -86,6 +98,10 @@ class $AssetsImagesDinoGen {
class $AssetsImagesSparkyGen { class $AssetsImagesSparkyGen {
const $AssetsImagesSparkyGen(); const $AssetsImagesSparkyGen();
/// File path: assets/images/sparky/animation.png
AssetGenImage get animation =>
const AssetGenImage('assets/images/sparky/animation.png');
/// File path: assets/images/sparky/background.png /// File path: assets/images/sparky/background.png
AssetGenImage get background => AssetGenImage get background =>
const AssetGenImage('assets/images/sparky/background.png'); const AssetGenImage('assets/images/sparky/background.png');

@ -14,9 +14,6 @@ class AndroidTheme extends CharacterTheme {
@override @override
Color get ballColor => Colors.green; Color get ballColor => Colors.green;
@override
AssetGenImage get character => Assets.images.android.character;
@override @override
AssetGenImage get background => Assets.images.android.background; AssetGenImage get background => Assets.images.android.background;
@ -25,4 +22,7 @@ class AndroidTheme extends CharacterTheme {
@override @override
AssetGenImage get leaderboardIcon => Assets.images.android.leaderboardIcon; AssetGenImage get leaderboardIcon => Assets.images.android.leaderboardIcon;
@override
AssetGenImage get animation => Assets.images.android.animation;
} }

@ -18,9 +18,6 @@ abstract class CharacterTheme extends Equatable {
/// Ball color for this theme. /// Ball color for this theme.
Color get ballColor; Color get ballColor;
/// Asset for the theme character.
AssetGenImage get character;
/// Asset for the background. /// Asset for the background.
AssetGenImage get background; AssetGenImage get background;
@ -30,13 +27,16 @@ abstract class CharacterTheme extends Equatable {
/// Icon asset for the leaderboard. /// Icon asset for the leaderboard.
AssetGenImage get leaderboardIcon; AssetGenImage get leaderboardIcon;
/// Asset for the the idle character animation.
AssetGenImage get animation;
@override @override
List<Object?> get props => [ List<Object?> get props => [
name, name,
ballColor, ballColor,
character,
background, background,
icon, icon,
leaderboardIcon, leaderboardIcon,
animation,
]; ];
} }

@ -14,9 +14,6 @@ class DashTheme extends CharacterTheme {
@override @override
Color get ballColor => Colors.blue; Color get ballColor => Colors.blue;
@override
AssetGenImage get character => Assets.images.dash.character;
@override @override
AssetGenImage get background => Assets.images.dash.background; AssetGenImage get background => Assets.images.dash.background;
@ -25,4 +22,7 @@ class DashTheme extends CharacterTheme {
@override @override
AssetGenImage get leaderboardIcon => Assets.images.dash.leaderboardIcon; AssetGenImage get leaderboardIcon => Assets.images.dash.leaderboardIcon;
@override
AssetGenImage get animation => Assets.images.dash.animation;
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save