|
|
|
@ -2,139 +2,76 @@ import 'dart:math' as math;
|
|
|
|
|
|
|
|
|
|
import 'package:flame/components.dart';
|
|
|
|
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:pinball_components/pinball_components.dart';
|
|
|
|
|
|
|
|
|
|
/// {@template dash_nest_bumper}
|
|
|
|
|
/// Bumper with a nest appearance.
|
|
|
|
|
/// {@endtemplate}
|
|
|
|
|
abstract class DashNestBumper extends BodyComponent with InitialPosition {
|
|
|
|
|
class DashNestBumper extends BodyComponent with InitialPosition {
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
DashNestBumper._({
|
|
|
|
|
required double majorRadius,
|
|
|
|
|
required double minorRadius,
|
|
|
|
|
required String activeAssetPath,
|
|
|
|
|
required String inactiveAssetPath,
|
|
|
|
|
required SpriteComponent spriteComponent,
|
|
|
|
|
}) : _activeAssetPath = activeAssetPath,
|
|
|
|
|
_inactiveAssetPath = inactiveAssetPath,
|
|
|
|
|
_spriteComponent = spriteComponent,
|
|
|
|
|
super(priority: RenderPriority.dashBumper);
|
|
|
|
|
|
|
|
|
|
final String _activeAssetPath;
|
|
|
|
|
late final Sprite _activeSprite;
|
|
|
|
|
final String _inactiveAssetPath;
|
|
|
|
|
late final Sprite _inactiveSprite;
|
|
|
|
|
final SpriteComponent _spriteComponent;
|
|
|
|
|
|
|
|
|
|
Future<void> _loadSprites() async {
|
|
|
|
|
// TODO(alestiago): I think ideally we would like to do:
|
|
|
|
|
// Sprite(path).load so we don't require to store the activeAssetPath and
|
|
|
|
|
// the inactive assetPath.
|
|
|
|
|
_inactiveSprite = await gameRef.loadSprite(_inactiveAssetPath);
|
|
|
|
|
_activeSprite = await gameRef.loadSprite(_activeAssetPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Activates the [DashNestBumper].
|
|
|
|
|
void activate() {
|
|
|
|
|
_spriteComponent
|
|
|
|
|
..sprite = _activeSprite
|
|
|
|
|
..size = _activeSprite.originalSize / 10;
|
|
|
|
|
required Vector2 spritePosition,
|
|
|
|
|
}) : _majorRadius = majorRadius,
|
|
|
|
|
_minorRadius = minorRadius,
|
|
|
|
|
super(
|
|
|
|
|
priority: RenderPriority.dashBumper,
|
|
|
|
|
children: [
|
|
|
|
|
_DashNestBumperSpriteGroupComponent(
|
|
|
|
|
activeAssetPath: activeAssetPath,
|
|
|
|
|
inactiveAssetPath: inactiveAssetPath,
|
|
|
|
|
position: spritePosition,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
) {
|
|
|
|
|
renderBody = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Deactivates the [DashNestBumper].
|
|
|
|
|
void deactivate() {
|
|
|
|
|
_spriteComponent
|
|
|
|
|
..sprite = _inactiveSprite
|
|
|
|
|
..size = _inactiveSprite.originalSize / 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> onLoad() async {
|
|
|
|
|
await super.onLoad();
|
|
|
|
|
await _loadSprites();
|
|
|
|
|
|
|
|
|
|
// TODO(erickzanardo): Look into using onNewState instead.
|
|
|
|
|
// Currently doing: onNewState(gameRef.read<GameState>()) will throw an
|
|
|
|
|
// `Exception: build context is not available yet`
|
|
|
|
|
deactivate();
|
|
|
|
|
await add(_spriteComponent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
class BigDashNestBumper extends DashNestBumper {
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
BigDashNestBumper()
|
|
|
|
|
: super._(
|
|
|
|
|
DashNestBumper.main()
|
|
|
|
|
: this._(
|
|
|
|
|
majorRadius: 5.1,
|
|
|
|
|
minorRadius: 3.75,
|
|
|
|
|
activeAssetPath: Assets.images.dash.bumper.main.active.keyName,
|
|
|
|
|
inactiveAssetPath: Assets.images.dash.bumper.main.inactive.keyName,
|
|
|
|
|
spriteComponent: SpriteComponent(
|
|
|
|
|
anchor: Anchor.center,
|
|
|
|
|
position: Vector2(0, -0.3),
|
|
|
|
|
),
|
|
|
|
|
spritePosition: Vector2(0, -0.3),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Body createBody() {
|
|
|
|
|
final shape = EllipseShape(
|
|
|
|
|
center: Vector2.zero(),
|
|
|
|
|
majorRadius: 5.1,
|
|
|
|
|
minorRadius: 3.75,
|
|
|
|
|
)..rotate(math.pi / 1.9);
|
|
|
|
|
final fixtureDef = FixtureDef(shape);
|
|
|
|
|
final bodyDef = BodyDef(
|
|
|
|
|
position: initialPosition,
|
|
|
|
|
userData: this,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
class SmallDashNestBumper extends DashNestBumper {
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
SmallDashNestBumper._({
|
|
|
|
|
required String activeAssetPath,
|
|
|
|
|
required String inactiveAssetPath,
|
|
|
|
|
required SpriteComponent spriteComponent,
|
|
|
|
|
}) : super._(
|
|
|
|
|
activeAssetPath: activeAssetPath,
|
|
|
|
|
inactiveAssetPath: inactiveAssetPath,
|
|
|
|
|
spriteComponent: spriteComponent,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
SmallDashNestBumper.a()
|
|
|
|
|
DashNestBumper.a()
|
|
|
|
|
: this._(
|
|
|
|
|
majorRadius: 3,
|
|
|
|
|
minorRadius: 2.5,
|
|
|
|
|
activeAssetPath: Assets.images.dash.bumper.a.active.keyName,
|
|
|
|
|
inactiveAssetPath: Assets.images.dash.bumper.a.inactive.keyName,
|
|
|
|
|
spriteComponent: SpriteComponent(
|
|
|
|
|
anchor: Anchor.center,
|
|
|
|
|
position: Vector2(0.35, -1.2),
|
|
|
|
|
),
|
|
|
|
|
spritePosition: Vector2(0.35, -1.2),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/// {@macro dash_nest_bumper}
|
|
|
|
|
SmallDashNestBumper.b()
|
|
|
|
|
DashNestBumper.b()
|
|
|
|
|
: this._(
|
|
|
|
|
majorRadius: 3,
|
|
|
|
|
minorRadius: 2.5,
|
|
|
|
|
activeAssetPath: Assets.images.dash.bumper.b.active.keyName,
|
|
|
|
|
inactiveAssetPath: Assets.images.dash.bumper.b.inactive.keyName,
|
|
|
|
|
spriteComponent: SpriteComponent(
|
|
|
|
|
anchor: Anchor.center,
|
|
|
|
|
position: Vector2(0.35, -1.2),
|
|
|
|
|
),
|
|
|
|
|
spritePosition: Vector2(0.35, -1.2),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final double _majorRadius;
|
|
|
|
|
final double _minorRadius;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Body createBody() {
|
|
|
|
|
final shape = EllipseShape(
|
|
|
|
|
center: Vector2.zero(),
|
|
|
|
|
majorRadius: 3,
|
|
|
|
|
minorRadius: 2.25,
|
|
|
|
|
)..rotate(math.pi / 2);
|
|
|
|
|
final fixtureDef = FixtureDef(
|
|
|
|
|
shape,
|
|
|
|
|
restitution: 4,
|
|
|
|
|
);
|
|
|
|
|
majorRadius: _majorRadius,
|
|
|
|
|
minorRadius: _minorRadius,
|
|
|
|
|
)..rotate(math.pi / 1.9);
|
|
|
|
|
final fixtureDef = FixtureDef(shape, restitution: 4);
|
|
|
|
|
final bodyDef = BodyDef(
|
|
|
|
|
position: initialPosition,
|
|
|
|
|
userData: this,
|
|
|
|
@ -142,4 +79,58 @@ class SmallDashNestBumper extends DashNestBumper {
|
|
|
|
|
|
|
|
|
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Activates the [DashNestBumper].
|
|
|
|
|
void activate() {
|
|
|
|
|
firstChild<_DashNestBumperSpriteGroupComponent>()?.current =
|
|
|
|
|
DashNestBumperSpriteState.active;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Deactivates the [DashNestBumper].
|
|
|
|
|
void deactivate() {
|
|
|
|
|
firstChild<_DashNestBumperSpriteGroupComponent>()?.current =
|
|
|
|
|
DashNestBumperSpriteState.inactive;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Indicates the [DashNestBumper]'s current sprite state.
|
|
|
|
|
@visibleForTesting
|
|
|
|
|
enum DashNestBumperSpriteState {
|
|
|
|
|
/// A lit up bumper.
|
|
|
|
|
active,
|
|
|
|
|
|
|
|
|
|
/// A dimmed bumper.
|
|
|
|
|
inactive,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _DashNestBumperSpriteGroupComponent
|
|
|
|
|
extends SpriteGroupComponent<DashNestBumperSpriteState> with HasGameRef {
|
|
|
|
|
_DashNestBumperSpriteGroupComponent({
|
|
|
|
|
required String activeAssetPath,
|
|
|
|
|
required String inactiveAssetPath,
|
|
|
|
|
required Vector2 position,
|
|
|
|
|
}) : _activeAssetPath = activeAssetPath,
|
|
|
|
|
_inactiveAssetPath = inactiveAssetPath,
|
|
|
|
|
super(
|
|
|
|
|
anchor: Anchor.center,
|
|
|
|
|
position: position,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final String _activeAssetPath;
|
|
|
|
|
final String _inactiveAssetPath;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> onLoad() async {
|
|
|
|
|
await super.onLoad();
|
|
|
|
|
final sprites = {
|
|
|
|
|
DashNestBumperSpriteState.active:
|
|
|
|
|
Sprite(gameRef.images.fromCache(_activeAssetPath)),
|
|
|
|
|
DashNestBumperSpriteState.inactive:
|
|
|
|
|
Sprite(gameRef.images.fromCache(_inactiveAssetPath)),
|
|
|
|
|
};
|
|
|
|
|
this.sprites = sprites;
|
|
|
|
|
|
|
|
|
|
current = DashNestBumperSpriteState.inactive;
|
|
|
|
|
size = sprites[current]!.originalSize / 10;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|