mirror of https://github.com/flutter/pinball.git
parent
75feeaae26
commit
221d055a1e
@ -1,3 +1,4 @@
|
||||
export 'android_spaceship_bonus_behavior.dart';
|
||||
export 'ramp_bonus_behavior.dart';
|
||||
export 'ramp_progress_behavior.dart';
|
||||
export 'ramp_shot_behavior.dart';
|
||||
|
@ -0,0 +1,69 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame_bloc/flame_bloc.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 ramp_progress_behavior}
|
||||
/// Increases the score when a [Ball] is shot into the [SpaceshipRamp].
|
||||
/// {@endtemplate}
|
||||
class RampProgressBehavior extends Component
|
||||
with ParentIsA<SpaceshipRamp>, FlameBlocReader<GameBloc, GameState> {
|
||||
/// {@macro ramp_shot_behavior}
|
||||
RampProgressBehavior() : super();
|
||||
|
||||
/// Creates a [RampProgressBehavior].
|
||||
///
|
||||
/// This can be used for testing [RampProgressBehavior] in isolation.
|
||||
@visibleForTesting
|
||||
RampProgressBehavior.test({
|
||||
required this.subscription,
|
||||
}) : super();
|
||||
|
||||
/// Subscription to [SpaceshipRampState] at [SpaceshipRamp].
|
||||
@visibleForTesting
|
||||
StreamSubscription? subscription;
|
||||
|
||||
@override
|
||||
void onMount() {
|
||||
super.onMount();
|
||||
|
||||
final spaceshipRamp = parent.children.whereType<SpaceshipRamp>().first;
|
||||
|
||||
var previousState = const SpaceshipRampState.initial();
|
||||
|
||||
subscription = subscription ??
|
||||
parent.bloc.stream.listen((state) {
|
||||
final listenWhen =
|
||||
previousState.hits != state.hits && state.hits != 0;
|
||||
if (listenWhen) {
|
||||
var fullArrowLit = spaceshipRamp.bloc.isFullyProgressed();
|
||||
var isMaxMultiplier = bloc.state.multiplier == 6;
|
||||
final canProgress =
|
||||
!isMaxMultiplier || (isMaxMultiplier && !fullArrowLit);
|
||||
|
||||
if (canProgress) {
|
||||
spaceshipRamp.bloc.onProgressed();
|
||||
}
|
||||
|
||||
fullArrowLit = spaceshipRamp.bloc.isFullyProgressed();
|
||||
isMaxMultiplier = bloc.state.multiplier == 6;
|
||||
|
||||
if (fullArrowLit && !isMaxMultiplier) {
|
||||
spaceshipRamp.bloc.onAnimate();
|
||||
}
|
||||
|
||||
previousState = state;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemove() {
|
||||
subscription?.cancel();
|
||||
super.onRemove();
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
export 'ramp_arrow_blinking_behavior.dart';
|
||||
export 'ramp_ball_ascending_contact_behavior.dart';
|
||||
|
@ -0,0 +1,77 @@
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:pinball_flame/pinball_flame.dart';
|
||||
|
||||
/// {@template ramp_arrow_blinking_behavior}
|
||||
/// Makes a [SpaceshipRampArrowSpriteComponent] blink between [ArrowLightState.values].
|
||||
/// {@endtemplate}
|
||||
class RampArrowBlinkingBehavior extends TimerComponent
|
||||
with ParentIsA<SpaceshipRamp> {
|
||||
/// {@macro ramp_arrow_blinking_behavior}
|
||||
RampArrowBlinkingBehavior() : super(period: 0.05);
|
||||
|
||||
final _maxBlinks = 15;
|
||||
|
||||
int _blinksCounter = 0;
|
||||
|
||||
bool _isAnimating = false;
|
||||
|
||||
void _onNewState(SpaceshipRampState state) {
|
||||
final animationEnabled =
|
||||
state.animationState == ArrowAnimationState.blinking;
|
||||
final canBlink = _blinksCounter < _maxBlinks;
|
||||
|
||||
if (animationEnabled && canBlink) {
|
||||
_start();
|
||||
} else {
|
||||
_stop();
|
||||
}
|
||||
}
|
||||
|
||||
void _start() {
|
||||
if (!_isAnimating) {
|
||||
_isAnimating = true;
|
||||
timer
|
||||
..reset()
|
||||
..start();
|
||||
_animate();
|
||||
}
|
||||
}
|
||||
|
||||
void _animate() {
|
||||
parent.bloc.onBlink();
|
||||
_blinksCounter++;
|
||||
}
|
||||
|
||||
void _stop() {
|
||||
if (_isAnimating) {
|
||||
_isAnimating = false;
|
||||
timer.stop();
|
||||
_blinksCounter = 0;
|
||||
parent.bloc.onStop();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
parent.bloc.stream.listen(_onNewState);
|
||||
}
|
||||
|
||||
@override
|
||||
void onTick() {
|
||||
super.onTick();
|
||||
if (!_isAnimating) {
|
||||
timer.stop();
|
||||
} else {
|
||||
if (_blinksCounter < _maxBlinks) {
|
||||
_animate();
|
||||
timer
|
||||
..reset()
|
||||
..start();
|
||||
} else {
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +1,64 @@
|
||||
// ignore_for_file: comment_references
|
||||
|
||||
part of 'spaceship_ramp_cubit.dart';
|
||||
|
||||
class SpaceshipRampState extends Equatable {
|
||||
const SpaceshipRampState({
|
||||
required this.hits,
|
||||
required this.lightState,
|
||||
required this.animationState,
|
||||
}) : assert(hits >= 0, "Hits can't be negative");
|
||||
|
||||
const SpaceshipRampState.initial() : this(hits: 0);
|
||||
const SpaceshipRampState.initial()
|
||||
: this(
|
||||
hits: 0,
|
||||
lightState: ArrowLightState.inactive,
|
||||
animationState: ArrowAnimationState.idle,
|
||||
);
|
||||
|
||||
final int hits;
|
||||
final ArrowLightState lightState;
|
||||
final ArrowAnimationState animationState;
|
||||
|
||||
SpaceshipRampState copyWith({
|
||||
int? hits,
|
||||
ArrowLightState? lightState,
|
||||
ArrowAnimationState? animationState,
|
||||
}) {
|
||||
return SpaceshipRampState(
|
||||
hits: hits ?? this.hits,
|
||||
lightState: lightState ?? this.lightState,
|
||||
animationState: animationState ?? this.animationState,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [hits];
|
||||
List<Object?> get props => [hits, lightState, animationState];
|
||||
}
|
||||
|
||||
/// Indicates the state of the arrow on the [SpaceshipRamp].
|
||||
enum ArrowLightState {
|
||||
/// Arrow with no dashes lit up.
|
||||
inactive,
|
||||
|
||||
/// Arrow with 1 light lit up.
|
||||
active1,
|
||||
|
||||
/// Arrow with 2 lights lit up.
|
||||
active2,
|
||||
|
||||
/// Arrow with 3 lights lit up.
|
||||
active3,
|
||||
|
||||
/// Arrow with 4 lights lit up.
|
||||
active4,
|
||||
|
||||
/// Arrow with all 5 lights lit up.
|
||||
active5,
|
||||
}
|
||||
|
||||
// Indicates if the blinking animation is running.
|
||||
enum ArrowAnimationState {
|
||||
idle,
|
||||
blinking,
|
||||
}
|
||||
|
Loading…
Reference in new issue