mirror of https://github.com/flutter/pinball.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.7 KiB
167 lines
4.7 KiB
import 'dart:async';
|
|
|
|
import 'package:flame/components.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:leaderboard_repository/leaderboard_repository.dart';
|
|
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
|
|
import 'package:pinball/game/components/backbox/displays/displays.dart';
|
|
import 'package:pinball/game/game.dart';
|
|
import 'package:pinball/l10n/l10n.dart';
|
|
import 'package:pinball_components/pinball_components.dart';
|
|
import 'package:pinball_flame/pinball_flame.dart';
|
|
import 'package:pinball_theme/pinball_theme.dart' hide Assets;
|
|
import 'package:pinball_ui/pinball_ui.dart';
|
|
import 'package:platform_helper/platform_helper.dart';
|
|
import 'package:share_repository/share_repository.dart';
|
|
|
|
/// {@template backbox}
|
|
/// The [Backbox] of the pinball machine.
|
|
/// {@endtemplate}
|
|
class Backbox extends PositionComponent with ZIndex, HasGameRef {
|
|
/// {@macro backbox}
|
|
Backbox({
|
|
required LeaderboardRepository leaderboardRepository,
|
|
required ShareRepository shareRepository,
|
|
required List<LeaderboardEntryData>? entries,
|
|
}) : _bloc = BackboxBloc(
|
|
leaderboardRepository: leaderboardRepository,
|
|
initialEntries: entries,
|
|
),
|
|
_shareRepository = shareRepository;
|
|
|
|
/// {@macro backbox}
|
|
@visibleForTesting
|
|
Backbox.test({
|
|
required BackboxBloc bloc,
|
|
required ShareRepository shareRepository,
|
|
}) : _bloc = bloc,
|
|
_shareRepository = shareRepository;
|
|
|
|
final ShareRepository _shareRepository;
|
|
late final Component _display;
|
|
final BackboxBloc _bloc;
|
|
late StreamSubscription<BackboxState> _subscription;
|
|
|
|
@override
|
|
Future<void> onLoad() async {
|
|
position = Vector2(0, -87);
|
|
anchor = Anchor.bottomCenter;
|
|
zIndex = ZIndexes.backbox;
|
|
|
|
await add(_BackboxSpriteComponent());
|
|
await add(_display = Component());
|
|
_build(_bloc.state);
|
|
|
|
_subscription = _bloc.stream.listen((state) {
|
|
final removals = _display.children.map((child) {
|
|
_display.remove(child);
|
|
return child.removed;
|
|
});
|
|
Future.wait(removals);
|
|
_build(state);
|
|
});
|
|
}
|
|
|
|
@override
|
|
void onRemove() {
|
|
super.onRemove();
|
|
_subscription.cancel();
|
|
}
|
|
|
|
void _build(BackboxState state) {
|
|
if (state is LoadingState) {
|
|
_display.add(LoadingDisplay());
|
|
} else if (state is LeaderboardSuccessState) {
|
|
_display.add(LeaderboardDisplay(entries: state.entries));
|
|
} else if (state is LeaderboardFailureState) {
|
|
_display.add(LeaderboardFailureDisplay());
|
|
} else if (state is InitialsFormState) {
|
|
if (readProvider<PlatformHelper>().isMobile) {
|
|
gameRef.overlays.add(PinballGame.mobileControlsOverlay);
|
|
}
|
|
_display.add(
|
|
InitialsInputDisplay(
|
|
score: state.score,
|
|
characterIconPath: state.character.leaderboardIcon.keyName,
|
|
onSubmit: (initials) {
|
|
_bloc.add(
|
|
PlayerInitialsSubmitted(
|
|
score: state.score,
|
|
initials: initials,
|
|
character: state.character,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
} else if (state is InitialsSuccessState) {
|
|
gameRef.overlays.remove(PinballGame.mobileControlsOverlay);
|
|
|
|
_display.add(
|
|
GameOverInfoDisplay(
|
|
onShare: () {
|
|
_bloc.add(ShareScoreRequested(score: state.score));
|
|
},
|
|
),
|
|
);
|
|
} else if (state is ShareState) {
|
|
_display.add(
|
|
ShareDisplay(
|
|
onShare: (platform) {
|
|
final message = readProvider<AppLocalizations>()
|
|
.iGotScoreAtPinball(state.score.formatScore());
|
|
final url = _shareRepository.shareText(
|
|
value: message,
|
|
platform: platform,
|
|
);
|
|
openLink(url);
|
|
},
|
|
),
|
|
);
|
|
} else if (state is InitialsFailureState) {
|
|
_display.add(
|
|
InitialsSubmissionFailureDisplay(
|
|
onDismissed: () {
|
|
_bloc.add(
|
|
PlayerInitialsRequested(
|
|
score: state.score,
|
|
character: state.character,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Puts [InitialsInputDisplay] on the [Backbox].
|
|
void requestInitials({
|
|
required int score,
|
|
required CharacterTheme character,
|
|
}) {
|
|
_bloc.add(
|
|
PlayerInitialsRequested(
|
|
score: score,
|
|
character: character,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _BackboxSpriteComponent extends SpriteComponent with HasGameRef {
|
|
_BackboxSpriteComponent() : super(anchor: Anchor.bottomCenter);
|
|
|
|
@override
|
|
Future<void> onLoad() async {
|
|
await super.onLoad();
|
|
|
|
final sprite = Sprite(
|
|
gameRef.images.fromCache(
|
|
Assets.images.backbox.marquee.keyName,
|
|
),
|
|
);
|
|
this.sprite = sprite;
|
|
size = sprite.originalSize / 20;
|
|
}
|
|
}
|