feat: add blinking assets

pull/283/head
Allison Ryan 3 years ago
parent 1641fae88e
commit a346419694

@ -36,7 +36,7 @@ class _BottomGroupSide extends Component {
@override
Future<void> onLoad() async {
final direction = _side.direction;
final centerXAdjustment = _side.isLeft ? 0 : -6.5;
final centerXAdjustment = _side.isLeft ? 0 : -6.66;
final flipper = ControlledFlipper(
side: _side,
@ -44,16 +44,17 @@ class _BottomGroupSide extends Component {
final baseboard = Baseboard(side: _side)
..initialPosition = Vector2(
(25.58 * direction) + centerXAdjustment,
28.69,
28.71,
);
final kicker = Kicker(
side: _side,
bloc: KickerCubit(),
children: [
ScoringBehavior(points: 5000),
ScoringBehavior(points: 5000)..applyTo(['bouncy_edge']),
],
)..initialPosition = Vector2(
(22.4 * direction) + centerXAdjustment,
25,
(22.64 * direction) + centerXAdjustment,
25.1,
);
await addAll([flipper, baseboard, kicker]);

@ -24,8 +24,10 @@ extension PinballGameAssetsX on PinballGame {
images.load(components.Assets.images.flipper.right.keyName),
images.load(components.Assets.images.baseboard.left.keyName),
images.load(components.Assets.images.baseboard.right.keyName),
images.load(components.Assets.images.kicker.left.keyName),
images.load(components.Assets.images.kicker.right.keyName),
images.load(components.Assets.images.kicker.left.lit.keyName),
images.load(components.Assets.images.kicker.left.dimmed.keyName),
images.load(components.Assets.images.kicker.right.lit.keyName),
images.load(components.Assets.images.kicker.right.dimmed.keyName),
images.load(components.Assets.images.slingshot.upper.keyName),
images.load(components.Assets.images.slingshot.lower.keyName),
images.load(components.Assets.images.launchRamp.ramp.keyName),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -169,13 +169,8 @@ class $AssetsImagesGoogleWordGen {
class $AssetsImagesKickerGen {
const $AssetsImagesKickerGen();
/// File path: assets/images/kicker/left.png
AssetGenImage get left =>
const AssetGenImage('assets/images/kicker/left.png');
/// File path: assets/images/kicker/right.png
AssetGenImage get right =>
const AssetGenImage('assets/images/kicker/right.png');
$AssetsImagesKickerLeftGen get left => const $AssetsImagesKickerLeftGen();
$AssetsImagesKickerRightGen get right => const $AssetsImagesKickerRightGen();
}
class $AssetsImagesLaunchRampGen {
@ -344,6 +339,30 @@ class $AssetsImagesDinoAnimatronicGen {
const AssetGenImage('assets/images/dino/animatronic/mouth.png');
}
class $AssetsImagesKickerLeftGen {
const $AssetsImagesKickerLeftGen();
/// File path: assets/images/kicker/left/dimmed.png
AssetGenImage get dimmed =>
const AssetGenImage('assets/images/kicker/left/dimmed.png');
/// File path: assets/images/kicker/left/lit.png
AssetGenImage get lit =>
const AssetGenImage('assets/images/kicker/left/lit.png');
}
class $AssetsImagesKickerRightGen {
const $AssetsImagesKickerRightGen();
/// File path: assets/images/kicker/right/dimmed.png
AssetGenImage get dimmed =>
const AssetGenImage('assets/images/kicker/right/dimmed.png');
/// File path: assets/images/kicker/right/lit.png
AssetGenImage get lit =>
const AssetGenImage('assets/images/kicker/right/lit.png');
}
class $AssetsImagesMultiplierX2Gen {
const $AssetsImagesMultiplierX2Gen();

@ -17,7 +17,7 @@ export 'flipper.dart';
export 'google_letter/google_letter.dart';
export 'initial_position.dart';
export 'joint_anchor.dart';
export 'kicker.dart';
export 'kicker/kicker.dart';
export 'launch_ramp.dart';
export 'layer.dart';
export 'layer_sensor.dart';

@ -0,0 +1,2 @@
export 'kicker_ball_contact_behavior.dart';
export 'kicker_blinking_behavior.dart';

@ -1 +1,14 @@
// ignore_for_file: public_member_api_docs
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
class KickerBallContactBehavior extends ContactBehavior<Kicker> {
@override
void beginContact(Object other, Contact contact) {
super.beginContact(other, contact);
if (other is! Ball) return;
parent.bloc.onBallContacted();
}
}

@ -1 +1,37 @@
import 'package:flame/components.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
/// {@template kicker_blinking_behavior}
/// Makes a [Kicker] blink back to [KickerState.lit] when [KickerState.dimmed].
/// {@endtemplate}
class KickerBlinkingBehavior extends TimerComponent with ParentIsA<Kicker> {
/// {@macro kicker_blinking_behavior}
KickerBlinkingBehavior() : super(period: 0.05);
void _onNewState(KickerState state) {
switch (state) {
case KickerState.lit:
break;
case KickerState.dimmed:
timer
..reset()
..start();
break;
}
}
@override
Future<void> onLoad() async {
await super.onLoad();
timer.stop();
parent.bloc.stream.listen(_onNewState);
}
@override
void onTick() {
super.onTick();
timer.stop();
parent.bloc.onBlinked();
}
}

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

@ -2,9 +2,15 @@ import 'dart:math' as math;
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart';
import 'package:geometry/geometry.dart' as geometry show centroid;
import 'package:pinball_components/gen/assets.gen.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_components/src/components/kicker/behaviors/behaviors.dart';
import 'package:pinball_flame/pinball_flame.dart';
export 'cubit/kicker_cubit.dart';
/// {@template kicker}
/// Triangular [BodyType.static] body that propels the [Ball] towards the
@ -16,16 +22,44 @@ class Kicker extends BodyComponent with InitialPosition {
/// {@macro kicker}
Kicker({
required BoardSide side,
required this.bloc,
Iterable<Component>? children,
}) : _side = side,
super(
children: [
_KickerSpriteComponent(side: side),
BumpingBehavior(strength: 15)..applyTo(['bouncy_edge']),
KickerBallContactBehavior()..applyTo(['bouncy_edge']),
KickerBlinkingBehavior(),
_KickerSpriteGroupComponent(
side: side,
state: bloc.state,
),
...?children,
],
renderBody: false,
);
/// Creates an [Kicker] without any children.
///
/// This can be used for testing [Kicker]'s behaviors in isolation.
// TODO(alestiago): Refactor injecting bloc once the following is merged:
// https://github.com/flame-engine/flame/pull/1538
@visibleForTesting
Kicker.test({
required this.bloc,
}) : _side = BoardSide.left;
// TODO(alestiago): Consider refactoring once the following is merged:
// https://github.com/flame-engine/flame/pull/1538
// ignore: public_member_api_docs
final KickerCubit bloc;
@override
void onRemove() {
bloc.close();
super.onRemove();
}
/// Whether the [Kicker] is on the left or right side of the board.
///
/// A [Kicker] with [BoardSide.left] propels the [Ball] to the right,
@ -86,8 +120,7 @@ class Kicker extends BodyComponent with InitialPosition {
FixtureDef(lowerCircle),
FixtureDef(wallFacingEdge),
FixtureDef(bottomEdge),
// TODO(alestiago): Add BumpingBehaviour.
FixtureDef(bouncyEdge),
FixtureDef(bouncyEdge, userData: 'bouncy_edge'),
];
// TODO(alestiago): Evaluate if there is value on centering the fixtures.
@ -121,25 +154,46 @@ class Kicker extends BodyComponent with InitialPosition {
}
}
class _KickerSpriteComponent extends SpriteComponent with HasGameRef {
_KickerSpriteComponent({required BoardSide side}) : _side = side;
class _KickerSpriteGroupComponent extends SpriteGroupComponent<KickerState>
with HasGameRef, ParentIsA<Kicker> {
_KickerSpriteGroupComponent({
required BoardSide side,
required KickerState state,
}) : _side = side,
super(
anchor: Anchor.center,
position: Vector2(0.7 * -side.direction, -2.2),
current: state,
);
final BoardSide _side;
@override
Future<void> onLoad() async {
await super.onLoad();
// TODO(alestiago): Used cached asset.
final sprite = await gameRef.loadSprite(
// TODO(alestiago): Consider refactoring once the following is merged:
// https://github.com/flame-engine/flame/pull/1538
// ignore: public_member_api_docs
parent.bloc.stream.listen((state) => current = state);
final sprites = {
KickerState.lit: Sprite(
gameRef.images.fromCache(
(_side.isLeft)
? Assets.images.kicker.left.keyName
: Assets.images.kicker.right.keyName,
);
this.sprite = sprite;
size = sprite.originalSize / 10;
anchor = Anchor.center;
position = Vector2(0.7 * -_side.direction, -2.2);
? Assets.images.kicker.left.lit.keyName
: Assets.images.kicker.right.lit.keyName,
),
),
KickerState.dimmed: Sprite(
gameRef.images.fromCache(
(_side.isLeft)
? Assets.images.kicker.left.dimmed.keyName
: Assets.images.kicker.right.dimmed.keyName,
),
),
};
this.sprites = sprites;
size = sprites[current]!.originalSize / 10;
}
}

@ -64,7 +64,8 @@ flutter:
- assets/images/android/bumper/a/
- assets/images/android/bumper/b/
- assets/images/android/bumper/cow/
- assets/images/kicker/
- assets/images/kicker/left/
- assets/images/kicker/right/
- assets/images/plunger/
- assets/images/slingshot/
- assets/images/sparky/

@ -3,6 +3,16 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart';
class KickerGame extends BallGame {
KickerGame()
: super(
imagesFileNames: [
Assets.images.kicker.left.lit.keyName,
Assets.images.kicker.left.dimmed.keyName,
Assets.images.kicker.right.lit.keyName,
Assets.images.kicker.right.dimmed.keyName,
],
);
static const description = '''
Shows how Kickers are rendered.
@ -17,9 +27,9 @@ class KickerGame extends BallGame {
final center = screenToWorld(camera.viewport.canvasSize! / 2);
await addAll(
[
Kicker(side: BoardSide.left)
Kicker(side: BoardSide.left, bloc: KickerCubit())
..initialPosition = Vector2(center.x - 8.8, center.y),
Kicker(side: BoardSide.right)
Kicker(side: BoardSide.right, bloc: KickerCubit())
..initialPosition = Vector2(center.x + 8.8, center.y),
],
);

Loading…
Cancel
Save