Merge branch 'main' into feat/score-assets

pull/276/head
RuiAlonso 3 years ago
commit 514963373d

@ -7,6 +7,7 @@
// ignore_for_file: public_member_api_docs
import 'package:authentication_repository/authentication_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
@ -15,16 +16,20 @@ import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/select_character/select_character.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_ui/pinball_ui.dart';
class App extends StatelessWidget {
const App({
Key? key,
required AuthenticationRepository authenticationRepository,
required LeaderboardRepository leaderboardRepository,
required PinballAudio pinballAudio,
}) : _leaderboardRepository = leaderboardRepository,
}) : _authenticationRepository = authenticationRepository,
_leaderboardRepository = leaderboardRepository,
_pinballAudio = pinballAudio,
super(key: key);
final AuthenticationRepository _authenticationRepository;
final LeaderboardRepository _leaderboardRepository;
final PinballAudio _pinballAudio;
@ -32,19 +37,21 @@ class App extends StatelessWidget {
Widget build(BuildContext context) {
return MultiRepositoryProvider(
providers: [
RepositoryProvider.value(value: _authenticationRepository),
RepositoryProvider.value(value: _leaderboardRepository),
RepositoryProvider.value(value: _pinballAudio),
],
child: BlocProvider(
create: (context) => CharacterThemeCubit(),
child: const MaterialApp(
child: MaterialApp(
title: 'I/O Pinball',
localizationsDelegates: [
theme: PinballTheme.standard,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
home: PinballGamePage(),
home: const PinballGamePage(),
),
),
);

@ -12,6 +12,7 @@ import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/widgets.dart';
class AppBlocObserver extends BlocObserver {
@ -28,9 +29,12 @@ class AppBlocObserver extends BlocObserver {
}
}
Future<void> bootstrap(
Future<Widget> Function(FirebaseFirestore firestore) builder,
) async {
typedef BootstrapBuilder = Future<Widget> Function(
FirebaseFirestore firestore,
FirebaseAuth firebaseAuth,
);
Future<void> bootstrap(BootstrapBuilder builder) async {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (details) {
log(details.exceptionAsString(), stackTrace: details.stack);
@ -39,7 +43,12 @@ Future<void> bootstrap(
await runZonedGuarded(
() async {
await BlocOverrides.runZoned(
() async => runApp(await builder(FirebaseFirestore.instance)),
() async => runApp(
await builder(
FirebaseFirestore.instance,
FirebaseAuth.instance,
),
),
blocObserver: AppBlocObserver(),
);
},

@ -1,7 +1,6 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_ui/pinball_ui.dart';
/// {@template footer}
@ -35,7 +34,7 @@ class _GoogleIO extends StatelessWidget {
final theme = Theme.of(context);
return Text(
l10n.footerGoogleIOText,
style: theme.textTheme.bodyText1!.copyWith(color: AppColors.white),
style: theme.textTheme.bodyText1!.copyWith(color: PinballColors.white),
);
}
}
@ -51,7 +50,7 @@ class _MadeWithFlutterAndFirebase extends StatelessWidget {
textAlign: TextAlign.center,
text: TextSpan(
text: l10n.footerMadeWithText,
style: theme.textTheme.bodyText1!.copyWith(color: AppColors.white),
style: theme.textTheme.bodyText1!.copyWith(color: PinballColors.white),
children: <TextSpan>[
TextSpan(
text: l10n.footerFlutterLinkText,

@ -12,4 +12,4 @@ export 'google_word/google_word.dart';
export 'launcher.dart';
export 'multipliers/multipliers.dart';
export 'scoring_behavior.dart';
export 'sparky_fire_zone.dart';
export 'sparky_scorch.dart';

@ -5,15 +5,13 @@ import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template sparky_fire_zone}
/// Area positioned at the top left of the board where the [Ball]
/// can bounce off [SparkyBumper]s.
///
/// When a [Ball] hits [SparkyBumper]s, the bumper animates.
/// {@template sparky_scorch}
/// Area positioned at the top left of the board containing the
/// [SparkyComputer], [SparkyAnimatronic], and [SparkyBumper]s.
/// {@endtemplate}
class SparkyFireZone extends Blueprint {
/// {@macro sparky_fire_zone}
SparkyFireZone()
class SparkyScorch extends Blueprint {
/// {@macro sparky_scorch}
SparkyScorch()
: super(
components: [
SparkyBumper.a(

@ -89,13 +89,14 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.android.bumper.cow.dimmed.keyName),
images.load(components.Assets.images.sparky.computer.top.keyName),
images.load(components.Assets.images.sparky.computer.base.keyName),
images.load(components.Assets.images.sparky.computer.glow.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.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.c.active.keyName),
images.load(components.Assets.images.sparky.bumper.c.inactive.keyName),
images.load(components.Assets.images.sparky.bumper.a.lit.keyName),
images.load(components.Assets.images.sparky.bumper.a.dimmed.keyName),
images.load(components.Assets.images.sparky.bumper.b.lit.keyName),
images.load(components.Assets.images.sparky.bumper.b.dimmed.keyName),
images.load(components.Assets.images.sparky.bumper.c.lit.keyName),
images.load(components.Assets.images.sparky.bumper.c.dimmed.keyName),
images.load(components.Assets.images.backboard.backboardScores.keyName),
images.load(components.Assets.images.backboard.backboardGameOver.keyName),
images.load(components.Assets.images.googleWord.letter1.keyName),

@ -54,7 +54,7 @@ class PinballGame extends Forge2DGame
unawaited(addFromBlueprint(launcher));
await add(Multipliers());
await add(FlutterForest());
await addFromBlueprint(SparkyFireZone());
await addFromBlueprint(SparkyScorch());
await addFromBlueprint(AndroidAcres());
await addFromBlueprint(DinoDesert());
unawaited(addFromBlueprint(Slingshots()));

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/gen/gen.dart';
import 'package:pinball/theme/app_colors.dart';
import 'package:pinball_ui/pinball_ui.dart';
/// {@template game_hud}
/// Overlay on the [PinballGame].
@ -72,7 +72,7 @@ class _ScoreViewDecoration extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: radius,
border: Border.all(
color: AppColors.white,
color: PinballColors.white,
width: borderWidth,
),
image: DecorationImage(

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_ui/pinball_ui.dart';
/// {@template round_count_display}
/// Colored square indicating if a round is available.
@ -20,9 +20,7 @@ class RoundCountDisplay extends StatelessWidget {
children: [
Text(
l10n.rounds,
style: AppTextStyle.subtitle1.copyWith(
color: AppColors.yellow,
),
style: Theme.of(context).textTheme.subtitle1,
),
const SizedBox(width: 8),
Row(
@ -53,9 +51,9 @@ class RoundIndicator extends StatelessWidget {
@override
Widget build(BuildContext context) {
final color = isActive ? AppColors.yellow : AppColors.yellow.withAlpha(128);
final color =
isActive ? PinballColors.yellow : PinballColors.yellow.withAlpha(128);
const size = 8.0;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Container(

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template score_view}
@ -38,9 +37,7 @@ class _GameOver extends StatelessWidget {
return Text(
l10n.gameOver,
style: AppTextStyle.headline1.copyWith(
color: AppColors.white,
),
style: Theme.of(context).textTheme.headline1,
);
}
}
@ -58,9 +55,7 @@ class _ScoreDisplay extends StatelessWidget {
children: [
Text(
l10n.score.toLowerCase(),
style: AppTextStyle.subtitle1.copyWith(
color: AppColors.yellow,
),
style: Theme.of(context).textTheme.subtitle1,
),
const _ScoreText(),
const RoundCountDisplay(),
@ -78,9 +73,7 @@ class _ScoreText extends StatelessWidget {
return Text(
score.formatScore(),
style: AppTextStyle.headline1.copyWith(
color: AppColors.white,
),
style: Theme.of(context).textTheme.headline1,
);
}
}

@ -5,16 +5,27 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'dart:async';
import 'package:authentication_repository/authentication_repository.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/app/app.dart';
import 'package:pinball/bootstrap.dart';
import 'package:pinball_audio/pinball_audio.dart';
void main() {
bootstrap((firestore) async {
bootstrap((firestore, firebaseAuth) async {
final leaderboardRepository = LeaderboardRepository(firestore);
final authenticationRepository = AuthenticationRepository(firebaseAuth);
final pinballAudio = PinballAudio();
unawaited(
Firebase.initializeApp().then(
(_) => authenticationRepository.authenticateAnonymously(),
),
);
return App(
authenticationRepository: authenticationRepository,
leaderboardRepository: leaderboardRepository,
pinballAudio: pinballAudio,
);

@ -5,16 +5,27 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'dart:async';
import 'package:authentication_repository/authentication_repository.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/app/app.dart';
import 'package:pinball/bootstrap.dart';
import 'package:pinball_audio/pinball_audio.dart';
void main() {
bootstrap((firestore) async {
bootstrap((firestore, firebaseAuth) async {
final leaderboardRepository = LeaderboardRepository(firestore);
final authenticationRepository = AuthenticationRepository(firebaseAuth);
final pinballAudio = PinballAudio();
unawaited(
Firebase.initializeApp().then(
(_) => authenticationRepository.authenticateAnonymously(),
),
);
return App(
authenticationRepository: authenticationRepository,
leaderboardRepository: leaderboardRepository,
pinballAudio: pinballAudio,
);

@ -5,16 +5,27 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'dart:async';
import 'package:authentication_repository/authentication_repository.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/app/app.dart';
import 'package:pinball/bootstrap.dart';
import 'package:pinball_audio/pinball_audio.dart';
void main() {
bootstrap((firestore) async {
bootstrap((firestore, firebaseAuth) async {
final leaderboardRepository = LeaderboardRepository(firestore);
final authenticationRepository = AuthenticationRepository(firebaseAuth);
final pinballAudio = PinballAudio();
unawaited(
Firebase.initializeApp().then(
(_) => authenticationRepository.authenticateAnonymously(),
),
);
return App(
authenticationRepository: authenticationRepository,
leaderboardRepository: leaderboardRepository,
pinballAudio: pinballAudio,
);

@ -5,7 +5,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:pinball/gen/gen.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_ui/pinball_ui.dart';
import 'package:platform_helper/platform_helper.dart';
@ -122,7 +121,7 @@ class _MobileLaunchControls extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
const textStyle = AppTextStyle.subtitle3;
final textStyle = Theme.of(context).textTheme.headline3;
return Column(
children: [
Text(
@ -138,9 +137,7 @@ class _MobileLaunchControls extends StatelessWidget {
),
TextSpan(
text: l10n.launch,
style: textStyle.copyWith(
color: AppColors.blue,
),
style: textStyle?.copyWith(color: PinballColors.blue),
),
],
),
@ -156,7 +153,7 @@ class _MobileFlipperControls extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
const textStyle = AppTextStyle.subtitle3;
final textStyle = Theme.of(context).textTheme.headline3;
return Column(
children: [
Text(
@ -172,9 +169,7 @@ class _MobileFlipperControls extends StatelessWidget {
),
TextSpan(
text: l10n.flip,
style: textStyle.copyWith(
color: AppColors.orange,
),
style: textStyle?.copyWith(color: PinballColors.orange),
),
],
),
@ -207,21 +202,22 @@ class _HowToPlayHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
const headerTextStyle = AppTextStyle.title;
final textStyle = Theme.of(context).textTheme.headline3?.copyWith(
color: PinballColors.darkBlue,
);
return FittedBox(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.howToPlay,
style: headerTextStyle.copyWith(
style: textStyle?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
l10n.tipsForFlips,
style: headerTextStyle,
style: textStyle,
),
],
),
@ -241,7 +237,7 @@ class _DesktopLaunchControls extends StatelessWidget {
children: [
Text(
l10n.launchControls,
style: AppTextStyle.headline4,
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 10),
Wrap(
@ -270,7 +266,7 @@ class _DesktopFlipperControls extends StatelessWidget {
children: [
Text(
l10n.flipperControls,
style: AppTextStyle.subtitle2,
style: Theme.of(context).textTheme.subtitle2,
),
const SizedBox(height: 10),
Column(
@ -311,8 +307,9 @@ class KeyButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final textStyle =
_control.isArrow ? AppTextStyle.headline1 : AppTextStyle.headline3;
_control.isArrow ? textTheme.headline1 : textTheme.headline3;
const height = 60.0;
final width = _control.isSpace ? height * 2.83 : height;
return DecoratedBox(
@ -334,7 +331,7 @@ class KeyButton extends StatelessWidget {
quarterTurns: _control.isDown ? 1 : 0,
child: Text(
_control.getCharacter(context),
style: textStyle.copyWith(color: AppColors.white),
style: textStyle?.copyWith(color: PinballColors.white),
),
),
),

@ -1,2 +0,0 @@
export 'app_colors.dart';
export 'app_text_style.dart';

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

@ -517,6 +517,10 @@ class $AssetsImagesSparkyComputerGen {
AssetGenImage get base =>
const AssetGenImage('assets/images/sparky/computer/base.png');
/// File path: assets/images/sparky/computer/glow.png
AssetGenImage get glow =>
const AssetGenImage('assets/images/sparky/computer/glow.png');
/// File path: assets/images/sparky/computer/top.png
AssetGenImage get top =>
const AssetGenImage('assets/images/sparky/computer/top.png');
@ -625,37 +629,37 @@ class $AssetsImagesDashBumperMainGen {
class $AssetsImagesSparkyBumperAGen {
const $AssetsImagesSparkyBumperAGen();
/// File path: assets/images/sparky/bumper/a/active.png
AssetGenImage get active =>
const AssetGenImage('assets/images/sparky/bumper/a/active.png');
/// File path: assets/images/sparky/bumper/a/dimmed.png
AssetGenImage get dimmed =>
const AssetGenImage('assets/images/sparky/bumper/a/dimmed.png');
/// File path: assets/images/sparky/bumper/a/inactive.png
AssetGenImage get inactive =>
const AssetGenImage('assets/images/sparky/bumper/a/inactive.png');
/// File path: assets/images/sparky/bumper/a/lit.png
AssetGenImage get lit =>
const AssetGenImage('assets/images/sparky/bumper/a/lit.png');
}
class $AssetsImagesSparkyBumperBGen {
const $AssetsImagesSparkyBumperBGen();
/// File path: assets/images/sparky/bumper/b/active.png
AssetGenImage get active =>
const AssetGenImage('assets/images/sparky/bumper/b/active.png');
/// File path: assets/images/sparky/bumper/b/dimmed.png
AssetGenImage get dimmed =>
const AssetGenImage('assets/images/sparky/bumper/b/dimmed.png');
/// File path: assets/images/sparky/bumper/b/inactive.png
AssetGenImage get inactive =>
const AssetGenImage('assets/images/sparky/bumper/b/inactive.png');
/// File path: assets/images/sparky/bumper/b/lit.png
AssetGenImage get lit =>
const AssetGenImage('assets/images/sparky/bumper/b/lit.png');
}
class $AssetsImagesSparkyBumperCGen {
const $AssetsImagesSparkyBumperCGen();
/// File path: assets/images/sparky/bumper/c/active.png
AssetGenImage get active =>
const AssetGenImage('assets/images/sparky/bumper/c/active.png');
/// File path: assets/images/sparky/bumper/c/dimmed.png
AssetGenImage get dimmed =>
const AssetGenImage('assets/images/sparky/bumper/c/dimmed.png');
/// File path: assets/images/sparky/bumper/c/inactive.png
AssetGenImage get inactive =>
const AssetGenImage('assets/images/sparky/bumper/c/inactive.png');
/// File path: assets/images/sparky/bumper/c/lit.png
AssetGenImage get lit =>
const AssetGenImage('assets/images/sparky/bumper/c/lit.png');
}
class Assets {

@ -115,7 +115,7 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
math.pow(defaultGravity, 2) - math.pow(positionalXForce, 2),
);
body.gravityOverride = Vector2(positionalXForce, positionalYForce);
body.gravityOverride = Vector2(-positionalXForce, positionalYForce);
}
}

@ -57,7 +57,7 @@ abstract class RenderPriority {
static const int rocket = _below + bottomBoundary;
// Dino Land
// Dino Desert
static const int dinoTopWall = _above + ballOnBoard;
@ -71,12 +71,14 @@ abstract class RenderPriority {
static const int flutterForest = _above + launchRampForegroundRailing;
// Sparky Fire Zone
// Sparky Scorch
static const int computerBase = _below + ballOnBoard;
static const int computerTop = _above + ballOnBoard;
static const int computerGlow = _above + ballOnBoard;
static const int sparkyAnimatronic = _above + spaceshipRampForegroundRailing;
static const int sparkyBumper = _above + ballOnBoard;

@ -3,19 +3,19 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template sparky_bumper_blinking_behavior}
/// Makes a [SparkyBumper] blink back to [SparkyBumperState.active] when
/// [SparkyBumperState.inactive].
/// Makes a [SparkyBumper] blink back to [SparkyBumperState.lit] when
/// [SparkyBumperState.dimmed].
/// {@endtemplate}
class SparkyBumperBlinkingBehavior extends TimerComponent
with ParentIsA<SparkyBumper> {
/// {@macro sparky_bumper_sprite_behavior}
/// {@macro sparky_bumper_blinking_behavior}
SparkyBumperBlinkingBehavior() : super(period: 0.05);
void _onNewState(SparkyBumperState state) {
switch (state) {
case SparkyBumperState.active:
case SparkyBumperState.lit:
break;
case SparkyBumperState.inactive:
case SparkyBumperState.dimmed:
timer
..reset()
..start();

@ -5,13 +5,13 @@ import 'package:bloc/bloc.dart';
part 'sparky_bumper_state.dart';
class SparkyBumperCubit extends Cubit<SparkyBumperState> {
SparkyBumperCubit() : super(SparkyBumperState.active);
SparkyBumperCubit() : super(SparkyBumperState.lit);
void onBallContacted() {
emit(SparkyBumperState.inactive);
emit(SparkyBumperState.dimmed);
}
void onBlinked() {
emit(SparkyBumperState.active);
emit(SparkyBumperState.lit);
}
}

@ -1,10 +1,8 @@
// ignore_for_file: public_member_api_docs
part of 'sparky_bumper_cubit.dart';
/// Indicates the [SparkyBumperCubit]'s current state.
enum SparkyBumperState {
/// A lit up bumper.
active,
/// A dimmed bumper.
inactive,
lit,
dimmed,
}

@ -17,8 +17,8 @@ class SparkyBumper extends BodyComponent with InitialPosition {
SparkyBumper._({
required double majorRadius,
required double minorRadius,
required String onAssetPath,
required String offAssetPath,
required String litAssetPath,
required String dimmedAssetPath,
required Vector2 spritePosition,
required this.bloc,
Iterable<Component>? children,
@ -31,8 +31,8 @@ class SparkyBumper extends BodyComponent with InitialPosition {
SparkyBumperBallContactBehavior(),
SparkyBumperBlinkingBehavior(),
_SparkyBumperSpriteGroupComponent(
onAssetPath: onAssetPath,
offAssetPath: offAssetPath,
litAssetPath: litAssetPath,
dimmedAssetPath: dimmedAssetPath,
position: spritePosition,
state: bloc.state,
),
@ -46,8 +46,8 @@ class SparkyBumper extends BodyComponent with InitialPosition {
}) : this._(
majorRadius: 2.9,
minorRadius: 2.1,
onAssetPath: Assets.images.sparky.bumper.a.active.keyName,
offAssetPath: Assets.images.sparky.bumper.a.inactive.keyName,
litAssetPath: Assets.images.sparky.bumper.a.lit.keyName,
dimmedAssetPath: Assets.images.sparky.bumper.a.dimmed.keyName,
spritePosition: Vector2(0, -0.25),
bloc: SparkyBumperCubit(),
children: children,
@ -59,8 +59,8 @@ class SparkyBumper extends BodyComponent with InitialPosition {
}) : this._(
majorRadius: 2.85,
minorRadius: 2,
onAssetPath: Assets.images.sparky.bumper.b.active.keyName,
offAssetPath: Assets.images.sparky.bumper.b.inactive.keyName,
litAssetPath: Assets.images.sparky.bumper.b.lit.keyName,
dimmedAssetPath: Assets.images.sparky.bumper.b.dimmed.keyName,
spritePosition: Vector2(0, -0.35),
bloc: SparkyBumperCubit(),
children: children,
@ -72,8 +72,8 @@ class SparkyBumper extends BodyComponent with InitialPosition {
}) : this._(
majorRadius: 3,
minorRadius: 2.2,
onAssetPath: Assets.images.sparky.bumper.c.active.keyName,
offAssetPath: Assets.images.sparky.bumper.c.inactive.keyName,
litAssetPath: Assets.images.sparky.bumper.c.lit.keyName,
dimmedAssetPath: Assets.images.sparky.bumper.c.dimmed.keyName,
spritePosition: Vector2(0, -0.4),
bloc: SparkyBumperCubit(),
children: children,
@ -127,20 +127,20 @@ class _SparkyBumperSpriteGroupComponent
extends SpriteGroupComponent<SparkyBumperState>
with HasGameRef, ParentIsA<SparkyBumper> {
_SparkyBumperSpriteGroupComponent({
required String onAssetPath,
required String offAssetPath,
required String litAssetPath,
required String dimmedAssetPath,
required Vector2 position,
required SparkyBumperState state,
}) : _onAssetPath = onAssetPath,
_offAssetPath = offAssetPath,
}) : _litAssetPath = litAssetPath,
_dimmedAssetPath = dimmedAssetPath,
super(
anchor: Anchor.center,
position: position,
current: state,
);
final String _onAssetPath;
final String _offAssetPath;
final String _litAssetPath;
final String _dimmedAssetPath;
@override
Future<void> onLoad() async {
@ -151,11 +151,11 @@ class _SparkyBumperSpriteGroupComponent
parent.bloc.stream.listen((state) => current = state);
final sprites = {
SparkyBumperState.active: Sprite(
gameRef.images.fromCache(_onAssetPath),
SparkyBumperState.lit: Sprite(
gameRef.images.fromCache(_litAssetPath),
),
SparkyBumperState.inactive: Sprite(
gameRef.images.fromCache(_offAssetPath),
SparkyBumperState.dimmed: Sprite(
gameRef.images.fromCache(_dimmedAssetPath),
),
};
this.sprites = sprites;

@ -15,6 +15,7 @@ class SparkyComputer extends Blueprint {
components: [
_ComputerBase(),
_ComputerTopSpriteComponent(),
_ComputerGlowSpriteComponent(),
],
);
}
@ -65,15 +66,17 @@ class _ComputerBaseSpriteComponent extends SpriteComponent with HasGameRef {
_ComputerBaseSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(-11.95, -48.35),
position: Vector2(-12.1, -48.15),
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.sparky.computer.base.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
@ -84,7 +87,7 @@ class _ComputerTopSpriteComponent extends SpriteComponent with HasGameRef {
_ComputerTopSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(-12.45, -49.75),
position: Vector2(-12.52, -49.37),
priority: RenderPriority.computerTop,
);
@ -92,8 +95,32 @@ class _ComputerTopSpriteComponent extends SpriteComponent with HasGameRef {
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.sparky.computer.top.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
}
}
class _ComputerGlowSpriteComponent extends SpriteComponent with HasGameRef {
_ComputerGlowSpriteComponent()
: super(
anchor: Anchor.center,
position: Vector2(7.4, 10),
priority: RenderPriority.computerGlow,
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.sparky.computer.glow.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;

@ -19,7 +19,7 @@ void main() {
addBottomGroupStories(dashbook);
addPlungerStories(dashbook);
addSlingshotStories(dashbook);
addSparkyBumperStories(dashbook);
addSparkyScorchStories(dashbook);
addAndroidAcresStories(dashbook);
addBoundariesStories(dashbook);
addGoogleWordStories(dashbook);

@ -15,7 +15,7 @@ class LaunchRampGame extends BallGame {
);
static const description = '''
Shows how LaunchRamp are rendered.
Shows how the LaunchRamp is rendered.
- Activate the "trace" parameter to overlay the body.
- Tap anywhere on the screen to spawn a ball into the game.
@ -26,7 +26,7 @@ class LaunchRampGame extends BallGame {
await super.onLoad();
camera
..followVector2(Vector2(0, 0))
..followVector2(Vector2.zero())
..zoom = 7.5;
await addFromBlueprint(LaunchRamp());
await ready();

@ -1,11 +0,0 @@
import 'package:dashbook/dashbook.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/sparky_bumper/sparky_bumper_game.dart';
void addSparkyBumperStories(Dashbook dashbook) {
dashbook.storiesOf('Sparky Bumpers').addGame(
title: 'Traced',
description: SparkyBumperGame.description,
gameBuilder: (_) => SparkyBumperGame(),
);
}

@ -9,6 +9,7 @@ class SparkyBumperGame extends BallGame {
Shows how a SparkyBumper is rendered.
- Activate the "trace" parameter to overlay the body.
- Tap anywhere on the screen to spawn a ball into the game.
''';
@override
@ -16,12 +17,12 @@ class SparkyBumperGame extends BallGame {
await super.onLoad();
await images.loadAll([
Assets.images.sparky.bumper.a.active.keyName,
Assets.images.sparky.bumper.a.inactive.keyName,
Assets.images.sparky.bumper.b.active.keyName,
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.sparky.bumper.a.lit.keyName,
Assets.images.sparky.bumper.a.dimmed.keyName,
Assets.images.sparky.bumper.b.lit.keyName,
Assets.images.sparky.bumper.b.dimmed.keyName,
Assets.images.sparky.bumper.c.lit.keyName,
Assets.images.sparky.bumper.c.dimmed.keyName,
]);
final center = screenToWorld(camera.viewport.canvasSize! / 2);

@ -0,0 +1,31 @@
import 'dart:async';
import 'package:flame/input.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart';
class SparkyComputerGame extends BallGame {
static const description = '''
Shows how the SparkyComputer is rendered.
- Activate the "trace" parameter to overlay the body.
- Tap anywhere on the screen to spawn a ball into the game.
''';
@override
Future<void> onLoad() async {
await super.onLoad();
await images.loadAll([
Assets.images.sparky.computer.base.keyName,
Assets.images.sparky.computer.top.keyName,
Assets.images.sparky.computer.glow.keyName,
]);
camera.followVector2(Vector2(-10, -40));
await addFromBlueprint(SparkyComputer());
await ready();
await traceAllBodies();
}
}

@ -0,0 +1,18 @@
import 'package:dashbook/dashbook.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/sparky_scorch/sparky_bumper_game.dart';
import 'package:sandbox/stories/sparky_scorch/sparky_computer_game.dart';
void addSparkyScorchStories(Dashbook dashbook) {
dashbook.storiesOf('Sparky Scorch')
..addGame(
title: 'Sparky Computer',
description: SparkyComputerGame.description,
gameBuilder: (_) => SparkyComputerGame(),
)
..addGame(
title: 'Sparky Bumper',
description: SparkyBumperGame.description,
gameBuilder: (_) => SparkyBumperGame(),
);
}

@ -14,4 +14,4 @@ export 'multipliers/stories.dart';
export 'plunger/stories.dart';
export 'score/stories.dart';
export 'slingshot/stories.dart';
export 'sparky_bumper/stories.dart';
export 'sparky_scorch/stories.dart';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 209 KiB

@ -31,7 +31,7 @@ void main() {
whenListen(
bloc,
const Stream<SparkyBumperState>.empty(),
initialState: SparkyBumperState.active,
initialState: SparkyBumperState.lit,
);
final sparkyBumper = SparkyBumper.test(bloc: bloc);

@ -17,7 +17,7 @@ void main() {
'SparkyBumperBlinkingBehavior',
() {
flameTester.testGameWidget(
'calls onBlinked after 0.05 seconds when inactive',
'calls onBlinked after 0.05 seconds when dimmed',
setUp: (game, tester) async {
final behavior = SparkyBumperBlinkingBehavior();
final bloc = MockSparkyBumperCubit();
@ -25,14 +25,14 @@ void main() {
whenListen(
bloc,
streamController.stream,
initialState: SparkyBumperState.active,
initialState: SparkyBumperState.lit,
);
final sparkyBumper = SparkyBumper.test(bloc: bloc);
await sparkyBumper.add(behavior);
await game.ensureAdd(sparkyBumper);
streamController.add(SparkyBumperState.inactive);
streamController.add(SparkyBumperState.dimmed);
await tester.pump();
game.update(0.05);

@ -7,17 +7,17 @@ void main() {
'SparkyBumperCubit',
() {
blocTest<SparkyBumperCubit, SparkyBumperState>(
'onBallContacted emits inactive',
'onBallContacted emits dimmed',
build: SparkyBumperCubit.new,
act: (bloc) => bloc.onBallContacted(),
expect: () => [SparkyBumperState.inactive],
expect: () => [SparkyBumperState.dimmed],
);
blocTest<SparkyBumperCubit, SparkyBumperState>(
'onBlinked emits active',
'onBlinked emits lit',
build: SparkyBumperCubit.new,
act: (bloc) => bloc.onBlinked(),
expect: () => [SparkyBumperState.active],
expect: () => [SparkyBumperState.lit],
);
},
);

@ -13,12 +13,12 @@ import '../../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.sparky.bumper.a.active.keyName,
Assets.images.sparky.bumper.a.inactive.keyName,
Assets.images.sparky.bumper.b.active.keyName,
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.sparky.bumper.a.lit.keyName,
Assets.images.sparky.bumper.a.dimmed.keyName,
Assets.images.sparky.bumper.b.lit.keyName,
Assets.images.sparky.bumper.b.dimmed.keyName,
Assets.images.sparky.bumper.c.lit.keyName,
Assets.images.sparky.bumper.c.dimmed.keyName,
];
final flameTester = FlameTester(() => TestGame(assets));
@ -49,7 +49,7 @@ void main() {
whenListen(
bloc,
const Stream<SparkyBumperState>.empty(),
initialState: SparkyBumperState.active,
initialState: SparkyBumperState.lit,
);
when(bloc.close).thenAnswer((_) async {});
final sparkyBumper = SparkyBumper.test(bloc: bloc);

@ -10,15 +10,33 @@ import '../../helpers/helpers.dart';
void main() {
group('SparkyComputer', () {
final tester = FlameTester(TestGame.new);
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.sparky.computer.base.keyName,
Assets.images.sparky.computer.top.keyName,
Assets.images.sparky.computer.glow.keyName,
];
final flameTester = FlameTester(() => TestGame(assets));
tester.testGameWidget(
flameTester.test(
'loads correctly',
(game) async {
await game.addFromBlueprint(SparkyComputer());
await game.ready();
},
);
flameTester.testGameWidget(
'renders correctly',
setUp: (game, tester) async {
await game.images.loadAll(assets);
await game.addFromBlueprint(SparkyComputer());
await game.ready();
await tester.pump();
game.camera.followVector2(Vector2(-15, -50));
game.camera
..followVector2(Vector2(0, -20))
..zoom = 7;
},
verify: (game, tester) async {
await expectLater(

@ -0,0 +1,16 @@
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
// ignore_for_file: directives_ordering,unnecessary_import
class FontFamily {
FontFamily._();
/// Font family: PixeloidMono
static const String pixeloidMono = 'PixeloidMono';
/// Font family: PixeloidSans
static const String pixeloidSans = 'PixeloidSans';
}

@ -5,3 +5,4 @@ export 'package:url_launcher_platform_interface/url_launcher_platform_interface.
export 'src/dialog/dialog.dart';
export 'src/external_links/external_links.dart';
export 'src/theme/theme.dart';

@ -1,17 +1,11 @@
// ignore_for_file: public_member_api_docs
import 'package:flutter/material.dart';
abstract class AppColors {
abstract class PinballColors {
static const Color white = Color(0xFFFFFFFF);
static const Color darkBlue = Color(0xFF0C32A4);
static const Color yellow = Color(0xFFFFEE02);
static const Color orange = Color(0xFFE5AB05);
static const Color blue = Color(0xFF4B94F6);
static const Color transparent = Color(0x00000000);
}

@ -1,17 +1,18 @@
// ignore_for_file: public_member_api_docs
import 'package:flutter/widgets.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_ui/gen/fonts.gen.dart';
import 'package:pinball_ui/pinball_ui.dart';
const _fontPackage = 'pinball_components';
const _primaryFontFamily = FontFamily.pixeloidSans;
abstract class AppTextStyle {
abstract class PinballTextStyle {
static const headline1 = TextStyle(
fontSize: 28,
package: _fontPackage,
fontFamily: _primaryFontFamily,
color: PinballColors.white,
);
static const headline2 = TextStyle(
@ -21,36 +22,22 @@ abstract class AppTextStyle {
);
static const headline3 = TextStyle(
color: AppColors.white,
color: PinballColors.white,
fontSize: 20,
package: _fontPackage,
fontFamily: _primaryFontFamily,
fontWeight: FontWeight.bold,
);
static const headline4 = TextStyle(
color: AppColors.white,
color: PinballColors.white,
fontSize: 16,
package: _fontPackage,
fontFamily: _primaryFontFamily,
);
static const title = TextStyle(
color: AppColors.darkBlue,
fontSize: 20,
package: _fontPackage,
fontFamily: _primaryFontFamily,
);
static const subtitle3 = TextStyle(
color: AppColors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
package: _fontPackage,
fontFamily: _primaryFontFamily,
);
static const subtitle2 = TextStyle(
color: AppColors.white,
color: PinballColors.white,
fontSize: 16,
package: _fontPackage,
fontFamily: _primaryFontFamily,
@ -60,5 +47,6 @@ abstract class AppTextStyle {
fontSize: 10,
fontFamily: _primaryFontFamily,
package: _fontPackage,
color: PinballColors.yellow,
);
}

@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:pinball_ui/pinball_ui.dart';
/// Pinball theme
class PinballTheme {
/// Standard [ThemeData] for Pinball UI
static ThemeData get standard {
return ThemeData(
textTheme: _textTheme,
);
}
static TextTheme get _textTheme {
return const TextTheme(
headline1: PinballTextStyle.headline1,
headline2: PinballTextStyle.headline2,
headline3: PinballTextStyle.headline3,
headline4: PinballTextStyle.headline4,
subtitle1: PinballTextStyle.subtitle1,
subtitle2: PinballTextStyle.subtitle2,
);
}
}

@ -0,0 +1,3 @@
export 'pinball_colors.dart';
export 'pinball_text_style.dart';
export 'pinball_theme.dart';

@ -23,6 +23,15 @@ flutter:
generate: true
assets:
- assets/images/dialog/
fonts:
- family: PixeloidSans
fonts:
- asset: fonts/PixeloidSans-nR3g1.ttf
- asset: fonts/PixeloidSansBold-RpeJo.ttf
weight: 700
- family: PixeloidMono
fonts:
- asset: fonts/PixeloidMono-1G8ae.ttf
flutter_gen:
line_length: 80

@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_ui/pinball_ui.dart';
void main() {
group('PinballColors', () {
test('white is 0xFFFFFFFF', () {
expect(PinballColors.white, const Color(0xFFFFFFFF));
});
test('darkBlue is 0xFF0C32A4', () {
expect(PinballColors.darkBlue, const Color(0xFF0C32A4));
});
test('yellow is 0xFFFFEE02', () {
expect(PinballColors.yellow, const Color(0xFFFFEE02));
});
test('orange is 0xFFE5AB05', () {
expect(PinballColors.orange, const Color(0xFFE5AB05));
});
test('blue is 0xFF4B94F6', () {
expect(PinballColors.blue, const Color(0xFF4B94F6));
});
test('transparent is 0x00000000', () {
expect(PinballColors.transparent, const Color(0x00000000));
});
});
}

@ -0,0 +1,41 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_ui/pinball_ui.dart';
void main() {
group('PinballTextStyle', () {
test('headline1 has fontSize 28 and white color', () {
const style = PinballTextStyle.headline1;
expect(style.fontSize, 28);
expect(style.color, PinballColors.white);
});
test('headline2 has fontSize 24', () {
const style = PinballTextStyle.headline2;
expect(style.fontSize, 24);
});
test('headline3 has fontSize 20 and white color', () {
const style = PinballTextStyle.headline3;
expect(style.fontSize, 20);
expect(style.color, PinballColors.white);
});
test('headline4 has fontSize 16 and white color', () {
const style = PinballTextStyle.headline4;
expect(style.fontSize, 16);
expect(style.color, PinballColors.white);
});
test('subtitle1 has fontSize 10 and yellow color', () {
const style = PinballTextStyle.subtitle1;
expect(style.fontSize, 10);
expect(style.color, PinballColors.yellow);
});
test('subtitle2 has fontSize 16 and white color', () {
const style = PinballTextStyle.subtitle2;
expect(style.fontSize, 16);
expect(style.color, PinballColors.white);
});
});
}

@ -0,0 +1,98 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_ui/pinball_ui.dart';
void main() {
group('PinballTheme', () {
group('standard', () {
test('headline1 matches PinballTextStyle#headline1', () {
expect(
PinballTheme.standard.textTheme.headline1!.fontSize,
PinballTextStyle.headline1.fontSize,
);
expect(
PinballTheme.standard.textTheme.headline1!.color,
PinballTextStyle.headline1.color,
);
expect(
PinballTheme.standard.textTheme.headline1!.fontFamily,
PinballTextStyle.headline1.fontFamily,
);
});
test('headline2 matches PinballTextStyle#headline2', () {
expect(
PinballTheme.standard.textTheme.headline2!.fontSize,
PinballTextStyle.headline2.fontSize,
);
expect(
PinballTheme.standard.textTheme.headline2!.fontFamily,
PinballTextStyle.headline2.fontFamily,
);
expect(
PinballTheme.standard.textTheme.headline2!.fontWeight,
PinballTextStyle.headline2.fontWeight,
);
});
test('headline3 matches PinballTextStyle#headline3', () {
expect(
PinballTheme.standard.textTheme.headline3!.fontSize,
PinballTextStyle.headline3.fontSize,
);
expect(
PinballTheme.standard.textTheme.headline3!.color,
PinballTextStyle.headline3.color,
);
expect(
PinballTheme.standard.textTheme.headline3!.fontFamily,
PinballTextStyle.headline3.fontFamily,
);
});
test('headline4 matches PinballTextStyle#headline4', () {
expect(
PinballTheme.standard.textTheme.headline4!.fontSize,
PinballTextStyle.headline4.fontSize,
);
expect(
PinballTheme.standard.textTheme.headline4!.color,
PinballTextStyle.headline4.color,
);
expect(
PinballTheme.standard.textTheme.headline4!.fontFamily,
PinballTextStyle.headline4.fontFamily,
);
});
test('subtitle1 matches PinballTextStyle#subtitle1', () {
expect(
PinballTheme.standard.textTheme.subtitle1!.fontSize,
PinballTextStyle.subtitle1.fontSize,
);
expect(
PinballTheme.standard.textTheme.subtitle1!.color,
PinballTextStyle.subtitle1.color,
);
expect(
PinballTheme.standard.textTheme.subtitle1!.fontFamily,
PinballTextStyle.subtitle1.fontFamily,
);
});
test('subtitle2 matches PinballTextStyle#subtitle2', () {
expect(
PinballTheme.standard.textTheme.subtitle2!.fontSize,
PinballTextStyle.subtitle2.fontSize,
);
expect(
PinballTheme.standard.textTheme.subtitle2!.color,
PinballTextStyle.subtitle2.color,
);
expect(
PinballTheme.standard.textTheme.subtitle2!.fontFamily,
PinballTextStyle.subtitle2.fontFamily,
);
});
});
});
}

@ -198,12 +198,12 @@ packages:
source: hosted
version: "3.3.13"
firebase_core:
dependency: transitive
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "1.13.1"
version: "1.15.0"
firebase_core_platform_interface:
dependency: transitive
description:

@ -13,6 +13,7 @@ dependencies:
cloud_firestore: ^3.1.10
equatable: ^2.0.3
firebase_auth: ^3.3.16
firebase_core: ^1.15.0
flame: ^1.1.1
flame_bloc: ^1.2.0
flame_forge2d:

@ -5,6 +5,7 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:authentication_repository/authentication_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:mocktail/mocktail.dart';
@ -16,19 +17,21 @@ import '../../helpers/mocks.dart';
void main() {
group('App', () {
late AuthenticationRepository authenticationRepository;
late LeaderboardRepository leaderboardRepository;
late PinballAudio pinballAudio;
setUp(() {
authenticationRepository = MockAuthenticationRepository();
leaderboardRepository = MockLeaderboardRepository();
pinballAudio = MockPinballAudio();
when(pinballAudio.load).thenAnswer((_) => Future.value());
});
testWidgets('renders PinballGamePage', (tester) async {
await tester.pumpWidget(
App(
authenticationRepository: authenticationRepository,
leaderboardRepository: leaderboardRepository,
pinballAudio: pinballAudio,
),

@ -12,22 +12,25 @@ import '../../helpers/helpers.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.sparky.bumper.a.active.keyName,
Assets.images.sparky.bumper.a.inactive.keyName,
Assets.images.sparky.bumper.b.active.keyName,
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.sparky.computer.top.keyName,
Assets.images.sparky.computer.base.keyName,
Assets.images.sparky.computer.glow.keyName,
Assets.images.sparky.animatronic.keyName,
Assets.images.sparky.bumper.a.lit.keyName,
Assets.images.sparky.bumper.a.dimmed.keyName,
Assets.images.sparky.bumper.b.lit.keyName,
Assets.images.sparky.bumper.b.dimmed.keyName,
Assets.images.sparky.bumper.c.lit.keyName,
Assets.images.sparky.bumper.c.dimmed.keyName,
];
final flameTester = FlameTester(
() => EmptyPinballTestGame(assets: assets),
);
group('SparkyFireZone', () {
group('SparkyScorch', () {
flameTester.test('loads correctly', (game) async {
await game.addFromBlueprint(SparkyFireZone());
await game.addFromBlueprint(SparkyScorch());
await game.ready();
});
@ -36,7 +39,7 @@ void main() {
'a SparkyComputer',
(game) async {
expect(
SparkyFireZone().blueprints.whereType<SparkyComputer>().single,
SparkyScorch().blueprints.whereType<SparkyComputer>().single,
isNotNull,
);
},
@ -45,8 +48,8 @@ void main() {
flameTester.test(
'a SparkyAnimatronic',
(game) async {
final sparkyFireZone = SparkyFireZone();
await game.addFromBlueprint(sparkyFireZone);
final sparkysScorch = SparkyScorch();
await game.addFromBlueprint(sparkysScorch);
await game.ready();
expect(
@ -59,8 +62,8 @@ void main() {
flameTester.test(
'three SparkyBumper',
(game) async {
final sparkyFireZone = SparkyFireZone();
await game.addFromBlueprint(sparkyFireZone);
final sparkysScorch = SparkyScorch();
await game.addFromBlueprint(sparkysScorch);
await game.ready();
expect(

@ -89,22 +89,17 @@ void main() {
Assets.images.android.ramp.arrow.active5.keyName,
Assets.images.android.rail.main.keyName,
Assets.images.android.rail.exit.keyName,
Assets.images.sparky.bumper.a.active.keyName,
Assets.images.sparky.bumper.a.inactive.keyName,
Assets.images.sparky.bumper.b.active.keyName,
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.sparky.animatronic.keyName,
Assets.images.sparky.computer.top.keyName,
Assets.images.sparky.computer.base.keyName,
Assets.images.sparky.computer.glow.keyName,
Assets.images.sparky.animatronic.keyName,
Assets.images.sparky.bumper.a.inactive.keyName,
Assets.images.sparky.bumper.a.active.keyName,
Assets.images.sparky.bumper.b.active.keyName,
Assets.images.sparky.bumper.b.inactive.keyName,
Assets.images.sparky.bumper.c.active.keyName,
Assets.images.sparky.bumper.c.inactive.keyName,
Assets.images.sparky.bumper.a.lit.keyName,
Assets.images.sparky.bumper.a.dimmed.keyName,
Assets.images.sparky.bumper.b.lit.keyName,
Assets.images.sparky.bumper.b.dimmed.keyName,
Assets.images.sparky.bumper.c.lit.keyName,
Assets.images.sparky.bumper.c.dimmed.keyName,
];
late GameBloc gameBloc;

@ -15,6 +15,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_ui/pinball_ui.dart';
import '../../../helpers/helpers.dart';
@ -56,6 +57,7 @@ void main() {
Future<void> _pumpAppWithWidget(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: PinballTheme.standard,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,

@ -2,7 +2,7 @@ import 'package:bloc_test/bloc_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/theme/app_colors.dart';
import 'package:pinball_ui/pinball_ui.dart';
import '../../../helpers/helpers.dart';
@ -108,7 +108,7 @@ void main() {
expect(
find.byWidgetPredicate(
(widget) => widget is Container && widget.color == AppColors.yellow,
(widget) => widget is Container && widget.color == PinballColors.yellow,
),
findsOneWidget,
);
@ -125,7 +125,7 @@ void main() {
find.byWidgetPredicate(
(widget) =>
widget is Container &&
widget.color == AppColors.yellow.withAlpha(128),
widget.color == PinballColors.yellow.withAlpha(128),
),
findsOneWidget,
);

@ -1,3 +1,4 @@
import 'package:authentication_repository/authentication_repository.dart';
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
@ -36,6 +37,9 @@ class MockGameState extends Mock implements GameState {}
class MockCharacterThemeCubit extends Mock implements CharacterThemeCubit {}
class MockAuthenticationRepository extends Mock
implements AuthenticationRepository {}
class MockLeaderboardRepository extends Mock implements LeaderboardRepository {}
class MockRawKeyDownEvent extends Mock implements RawKeyDownEvent {

@ -17,6 +17,7 @@ import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/select_character/select_character.dart';
import 'package:pinball/start_game/start_game.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_ui/pinball_ui.dart';
import 'helpers.dart';
@ -85,6 +86,7 @@ extension PumpApp on WidgetTester {
),
],
child: MaterialApp(
theme: PinballTheme.standard,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,11 +1,11 @@
if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
firebase.initializeApp({
"apiKey": "API_KEY",
"appId": "APP_ID",
"authDomain": "AUTH_DOMAIN",
"apiKey": "AIzaSyBgMVAvYccjNypCDdpW0ol6syCcISU2yjM",
"appId": "1:725488140557:web:7c61a0755fc23436fe7044",
"authDomain": "pinball-dev.firebaseapp.com",
"databaseURL": "",
"measurementId": "MEASUREMENT_ID",
"messagingSenderId": "MEASUREMENT_SENDER_ID",
"projectId": "PROJECT_ID",
"storageBucket": "STORAGE_BUCKET"
"measurementId": "G-9NW8SZRFJR",
"messagingSenderId": "725488140557",
"projectId": "pinball-dev",
"storageBucket": "pinball-dev.appspot.com"
});

@ -71,8 +71,9 @@
ga('create', 'UA-67589403-1', 'auto');
ga('send', 'pageview');
</script>
<script src="/__/firebase/8.9.1/firebase-app.js"></script>
<script src="/__/firebase/8.9.1/firebase-firestore.js"></script>
<script src="/__/firebase/8.10.1/firebase-app.js"></script>
<script src="/__/firebase/8.10.1/firebase-firestore.js"></script>
<script src="/__/firebase/8.10.1/firebase-auth.js"></script>
<script src="/__/firebase/init.js"></script>
</head>

Loading…
Cancel
Save