@ -0,0 +1,18 @@
|
||||
name: share_repository
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "packages/share_repository/**"
|
||||
- ".github/workflows/share_repository.yaml"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- "packages/share_repository/**"
|
||||
- ".github/workflows/share_repository.yaml"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
|
||||
with:
|
||||
working_directory: packages/share_repository
|
@ -1,52 +0,0 @@
|
||||
// ignore_for_file: avoid_renaming_method_parameters
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.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 controlled_sparky_computer}
|
||||
/// [SparkyComputer] with a [SparkyComputerController] attached.
|
||||
/// {@endtemplate}
|
||||
class ControlledSparkyComputer extends SparkyComputer
|
||||
with Controls<SparkyComputerController>, HasGameRef<Forge2DGame> {
|
||||
/// {@macro controlled_sparky_computer}
|
||||
ControlledSparkyComputer() : super() {
|
||||
controller = SparkyComputerController(this);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
gameRef.addContactCallback(SparkyComputerSensorBallContactCallback());
|
||||
}
|
||||
}
|
||||
|
||||
/// {@template sparky_computer_controller}
|
||||
/// Controller attached to a [SparkyComputer] that handles its game related
|
||||
/// logic.
|
||||
/// {@endtemplate}
|
||||
// TODO(allisonryan0002): listen for turbo charge game bonus and animate Sparky.
|
||||
class SparkyComputerController
|
||||
extends ComponentController<ControlledSparkyComputer> {
|
||||
/// {@macro sparky_computer_controller}
|
||||
SparkyComputerController(ControlledSparkyComputer controlledComputer)
|
||||
: super(controlledComputer);
|
||||
}
|
||||
|
||||
/// {@template sparky_computer_sensor_ball_contact_callback}
|
||||
/// Turbo charges the [Ball] when it enters the [SparkyComputer]
|
||||
/// {@endtemplate}
|
||||
@visibleForTesting
|
||||
class SparkyComputerSensorBallContactCallback
|
||||
extends ContactCallback<SparkyComputerSensor, ControlledBall> {
|
||||
/// {@macro sparky_computer_sensor_ball_contact_callback}
|
||||
SparkyComputerSensorBallContactCallback();
|
||||
|
||||
@override
|
||||
void begin(_, ControlledBall ball, __) {
|
||||
ball.controller.turboCharge();
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 365 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.1 KiB |
@ -0,0 +1,46 @@
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
|
||||
/// {@template sparky_animatronic}
|
||||
/// Animated Sparky that sits on top of the [SparkyComputer].
|
||||
/// {@endtemplate}
|
||||
class SparkyAnimatronic extends SpriteAnimationComponent with HasGameRef {
|
||||
/// {@macro sparky_animatronic}
|
||||
SparkyAnimatronic()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
playing: false,
|
||||
priority: RenderPriority.sparkyAnimatronic,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
|
||||
final spriteSheet = gameRef.images.fromCache(
|
||||
Assets.images.sparky.animatronic.keyName,
|
||||
);
|
||||
|
||||
const amountPerRow = 9;
|
||||
const amountPerColumn = 7;
|
||||
final textureSize = Vector2(
|
||||
spriteSheet.width / amountPerRow,
|
||||
spriteSheet.height / amountPerColumn,
|
||||
);
|
||||
size = textureSize / 10;
|
||||
|
||||
animation = SpriteAnimation.fromFrameData(
|
||||
spriteSheet,
|
||||
SpriteAnimationData.sequenced(
|
||||
amount: (amountPerRow * amountPerColumn) - 1,
|
||||
amountPerRow: amountPerRow,
|
||||
stepTime: 1 / 24,
|
||||
textureSize: textureSize,
|
||||
loop: false,
|
||||
),
|
||||
)..onComplete = () {
|
||||
animation?.reset();
|
||||
playing = false;
|
||||
};
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 34 KiB |
@ -0,0 +1,76 @@
|
||||
// ignore_for_file: cascade_invocations
|
||||
|
||||
import 'package:flame/extensions.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();
|
||||
|
||||
group('SparkyAnimatronic', () {
|
||||
final asset = Assets.images.sparky.animatronic.keyName;
|
||||
final flameTester = FlameTester(() => TestGame([asset]));
|
||||
|
||||
flameTester.testGameWidget(
|
||||
'renders correctly',
|
||||
setUp: (game, tester) async {
|
||||
await game.images.load(asset);
|
||||
await game.ensureAdd(SparkyAnimatronic()..playing = true);
|
||||
await tester.pump();
|
||||
|
||||
game.camera.followVector2(Vector2.zero());
|
||||
},
|
||||
verify: (game, tester) async {
|
||||
final animationDuration =
|
||||
game.firstChild<SparkyAnimatronic>()!.animation!.totalDuration();
|
||||
|
||||
await expectLater(
|
||||
find.byGame<TestGame>(),
|
||||
matchesGoldenFile('golden/sparky_animatronic/start.png'),
|
||||
);
|
||||
|
||||
game.update(animationDuration * 0.25);
|
||||
await tester.pump();
|
||||
await expectLater(
|
||||
find.byGame<TestGame>(),
|
||||
matchesGoldenFile('golden/sparky_animatronic/middle.png'),
|
||||
);
|
||||
|
||||
game.update(animationDuration * 0.75);
|
||||
await tester.pump();
|
||||
await expectLater(
|
||||
find.byGame<TestGame>(),
|
||||
matchesGoldenFile('golden/sparky_animatronic/end.png'),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
flameTester.test(
|
||||
'loads correctly',
|
||||
(game) async {
|
||||
final sparkyAnimatronic = SparkyAnimatronic();
|
||||
await game.ensureAdd(sparkyAnimatronic);
|
||||
|
||||
expect(game.contains(sparkyAnimatronic), isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
flameTester.test(
|
||||
'stops animating after animation completes',
|
||||
(game) async {
|
||||
final sparkyAnimatronic = SparkyAnimatronic();
|
||||
await game.ensureAdd(sparkyAnimatronic);
|
||||
|
||||
sparkyAnimatronic.playing = true;
|
||||
final animationDuration =
|
||||
game.firstChild<SparkyAnimatronic>()!.animation!.totalDuration();
|
||||
game.update(animationDuration);
|
||||
|
||||
expect(sparkyAnimatronic.playing, isFalse);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 226 KiB |
Before Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 206 KiB |
Before Width: | Height: | Size: 5.0 KiB |
@ -0,0 +1,7 @@
|
||||
# See https://www.dartlang.org/guides/libraries/private-files
|
||||
|
||||
# Files and directories created by pub
|
||||
.dart_tool/
|
||||
.packages
|
||||
build/
|
||||
pubspec.lock
|
@ -0,0 +1,11 @@
|
||||
# share_repository
|
||||
|
||||
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link]
|
||||
[![License: MIT][license_badge]][license_link]
|
||||
|
||||
Repository to facilitate sharing scores.
|
||||
|
||||
[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[license_link]: https://opensource.org/licenses/MIT
|
||||
[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg
|
||||
[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis
|
@ -0,0 +1 @@
|
||||
include: package:very_good_analysis/analysis_options.2.4.0.yaml
|
@ -0,0 +1,3 @@
|
||||
library share_repository;
|
||||
|
||||
export 'src/share_repository.dart';
|
@ -0,0 +1,7 @@
|
||||
/// {@template share_repository}
|
||||
/// Repository to facilitate sharing scores.
|
||||
/// {@endtemplate}
|
||||
class ShareRepository {
|
||||
/// {@macro share_repository}
|
||||
const ShareRepository();
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
name: share_repository
|
||||
description: Repository to facilitate sharing scores.
|
||||
version: 1.0.0+1
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=2.16.0 <3.0.0"
|
||||
|
||||
dev_dependencies:
|
||||
coverage: ^1.1.0
|
||||
mocktail: ^0.2.0
|
||||
test: ^1.19.2
|
||||
very_good_analysis: ^2.4.0
|
@ -0,0 +1,11 @@
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
import 'package:share_repository/share_repository.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('ShareRepository', () {
|
||||
test('can be instantiated', () {
|
||||
expect(ShareRepository(), isNotNull);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// ignore_for_file: cascade_invocations
|
||||
|
||||
import 'package:flame_test/flame_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:pinball/game/game.dart';
|
||||
|
||||
import '../../helpers/helpers.dart';
|
||||
|
||||
void main() {
|
||||
group('ControlledSparkyComputer', () {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
final flameTester = FlameTester(EmptyPinballTestGame.new);
|
||||
|
||||
flameTester.test('loads correctly', (game) async {
|
||||
final sparkyComputer = ControlledSparkyComputer();
|
||||
await game.ensureAdd(sparkyComputer);
|
||||
expect(game.children, contains(sparkyComputer));
|
||||
});
|
||||
|
||||
flameTester.testGameWidget(
|
||||
'SparkyTurboChargeSensorBallContactCallback turbo charges the ball',
|
||||
setUp: (game, tester) async {
|
||||
final contackCallback = SparkyComputerSensorBallContactCallback();
|
||||
final sparkyTurboChargeSensor = MockSparkyComputerSensor();
|
||||
final ball = MockControlledBall();
|
||||
final controller = MockBallController();
|
||||
|
||||
when(() => ball.controller).thenReturn(controller);
|
||||
when(controller.turboCharge).thenAnswer((_) async {});
|
||||
|
||||
contackCallback.begin(sparkyTurboChargeSensor, ball, MockContact());
|
||||
|
||||
verify(() => ball.controller.turboCharge()).called(1);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|