mirror of https://github.com/flutter/pinball.git
parent
125106f7eb
commit
ff668c0371
@ -0,0 +1,115 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pinball_components/gen/assets.gen.dart';
|
||||||
|
|
||||||
|
/// {@template multiball}
|
||||||
|
/// A [Component] for the multiball over the board.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Multiball extends Component {
|
||||||
|
/// {@macro multiball}
|
||||||
|
Multiball._({
|
||||||
|
required Vector2 position,
|
||||||
|
required String onAssetPath,
|
||||||
|
required String offAssetPath,
|
||||||
|
double rotation = 0,
|
||||||
|
}) : super(
|
||||||
|
children: [
|
||||||
|
MultiballSpriteGroupComponent(
|
||||||
|
position: position,
|
||||||
|
onAssetPath: onAssetPath,
|
||||||
|
offAssetPath: offAssetPath,
|
||||||
|
)..angle = rotation,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
/// {@macro multiball}
|
||||||
|
Multiball.a()
|
||||||
|
: this._(
|
||||||
|
position: Vector2(0, 0),
|
||||||
|
onAssetPath: Assets.images.multiball.a.active.keyName,
|
||||||
|
offAssetPath: Assets.images.multiball.a.inactive.keyName,
|
||||||
|
rotation: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// {@macro multiball}
|
||||||
|
Multiball.b()
|
||||||
|
: this._(
|
||||||
|
position: Vector2(0, 0),
|
||||||
|
onAssetPath: Assets.images.multiball.b.active.keyName,
|
||||||
|
offAssetPath: Assets.images.multiball.b.inactive.keyName,
|
||||||
|
rotation: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// {@macro multiball}
|
||||||
|
Multiball.c()
|
||||||
|
: this._(
|
||||||
|
position: Vector2(0, 0),
|
||||||
|
onAssetPath: Assets.images.multiball.c.active.keyName,
|
||||||
|
offAssetPath: Assets.images.multiball.c.inactive.keyName,
|
||||||
|
rotation: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// {@macro multiball}
|
||||||
|
Multiball.d()
|
||||||
|
: this._(
|
||||||
|
position: Vector2(0, 0),
|
||||||
|
onAssetPath: Assets.images.multiball.d.active.keyName,
|
||||||
|
offAssetPath: Assets.images.multiball.d.inactive.keyName,
|
||||||
|
rotation: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Animates the [Multiball].
|
||||||
|
Future<void> animate() async {
|
||||||
|
final spriteGroupComponent = firstChild<MultiballSpriteGroupComponent>()
|
||||||
|
?..current = MultiballSpriteState.active;
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||||
|
spriteGroupComponent?.current = MultiballSpriteState.inactive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates the current sprite state of the multiball.
|
||||||
|
enum MultiballSpriteState {
|
||||||
|
/// A lit up multiball.
|
||||||
|
active,
|
||||||
|
|
||||||
|
/// A dimmed multiball.
|
||||||
|
inactive,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// {@template multiball_sprite_group_component}
|
||||||
|
/// A [SpriteGroupComponent] for the multiball over the board.
|
||||||
|
/// {@endtemplate}
|
||||||
|
@visibleForTesting
|
||||||
|
class MultiballSpriteGroupComponent
|
||||||
|
extends SpriteGroupComponent<MultiballSpriteState> with HasGameRef {
|
||||||
|
/// {@macro multiball_sprite_group_component}
|
||||||
|
MultiballSpriteGroupComponent({
|
||||||
|
required Vector2 position,
|
||||||
|
required String onAssetPath,
|
||||||
|
required String offAssetPath,
|
||||||
|
}) : _onAssetPath = onAssetPath,
|
||||||
|
_offAssetPath = offAssetPath,
|
||||||
|
super(
|
||||||
|
anchor: Anchor.center,
|
||||||
|
position: position,
|
||||||
|
);
|
||||||
|
|
||||||
|
final String _onAssetPath;
|
||||||
|
final String _offAssetPath;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
await super.onLoad();
|
||||||
|
|
||||||
|
final sprites = {
|
||||||
|
MultiballSpriteState.active:
|
||||||
|
Sprite(gameRef.images.fromCache(_onAssetPath)),
|
||||||
|
MultiballSpriteState.inactive:
|
||||||
|
Sprite(gameRef.images.fromCache(_offAssetPath)),
|
||||||
|
};
|
||||||
|
this.sprites = sprites;
|
||||||
|
|
||||||
|
current = MultiballSpriteState.inactive;
|
||||||
|
size = sprites[current]!.originalSize / 10;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'package:flame/components.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();
|
||||||
|
final assets = [
|
||||||
|
Assets.images.multiball.a.active.keyName,
|
||||||
|
Assets.images.multiball.a.inactive.keyName,
|
||||||
|
Assets.images.multiball.b.active.keyName,
|
||||||
|
Assets.images.multiball.b.inactive.keyName,
|
||||||
|
Assets.images.multiball.c.active.keyName,
|
||||||
|
Assets.images.multiball.c.inactive.keyName,
|
||||||
|
Assets.images.multiball.d.active.keyName,
|
||||||
|
Assets.images.multiball.d.inactive.keyName,
|
||||||
|
];
|
||||||
|
final flameTester = FlameTester(() => TestGame(assets));
|
||||||
|
|
||||||
|
group('Multiball', () {
|
||||||
|
flameTester.test('"a" loads correctly', (game) async {
|
||||||
|
final multiball = Multiball.a();
|
||||||
|
await game.ensureAdd(multiball);
|
||||||
|
|
||||||
|
expect(game.contains(multiball), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('"b" loads correctly', (game) async {
|
||||||
|
final multiball = Multiball.b();
|
||||||
|
await game.ensureAdd(multiball);
|
||||||
|
expect(game.contains(multiball), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('"c" loads correctly', (game) async {
|
||||||
|
final multiball = Multiball.c();
|
||||||
|
await game.ensureAdd(multiball);
|
||||||
|
|
||||||
|
expect(game.contains(multiball), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('"d" loads correctly', (game) async {
|
||||||
|
final multiball = Multiball.d();
|
||||||
|
await game.ensureAdd(multiball);
|
||||||
|
expect(game.contains(multiball), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('animate switches between on and off sprites',
|
||||||
|
(game) async {
|
||||||
|
final multiball = Multiball.a();
|
||||||
|
await game.ensureAdd(multiball);
|
||||||
|
|
||||||
|
final spriteGroupComponent =
|
||||||
|
multiball.firstChild<SpriteGroupComponent>()!;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteGroupComponent.current,
|
||||||
|
equals(MultiballSpriteState.inactive),
|
||||||
|
);
|
||||||
|
|
||||||
|
final future = multiball.animate();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteGroupComponent.current,
|
||||||
|
equals(MultiballSpriteState.active),
|
||||||
|
);
|
||||||
|
|
||||||
|
await future;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteGroupComponent.current,
|
||||||
|
equals(MultiballSpriteState.inactive),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in new issue