Merge branch 'feat/spaceship-animation-and-assets' of https://github.com/VGVentures/pinball into feat/spaceship-animation-and-assets

pull/258/head
Allison Ryan 3 years ago
commit 06e1322a30

@ -0,0 +1,23 @@
name: pinball_ui
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
paths:
- "packages/pinball_ui/**"
- ".github/workflows/pinball_ui.yaml"
pull_request:
paths:
- "packages/pinball_ui/**"
- ".github/workflows/pinball_ui.yaml"
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
working_directory: packages/pinball_ui
coverage_excludes: "lib/gen/*.dart"

@ -12,9 +12,9 @@ class Launcher extends Blueprint {
Launcher()
: super(
components: [
ControlledPlunger(compressionDistance: 14)
..initialPosition = Vector2(40.7, 38),
RocketSpriteComponent()..position = Vector2(43, 62),
ControlledPlunger(compressionDistance: 10.5)
..initialPosition = Vector2(41.1, 43),
RocketSpriteComponent()..position = Vector2(43, 62.3),
],
blueprints: [LaunchRamp()],
);

@ -66,14 +66,14 @@ class _ScoreViewDecoration extends StatelessWidget {
@override
Widget build(BuildContext context) {
const radius = BorderRadius.all(Radius.circular(12));
const boardWidth = 5.0;
const borderWidth = 5.0;
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: radius,
border: Border.all(
color: AppColors.white,
width: boardWidth,
width: borderWidth,
),
image: DecorationImage(
fit: BoxFit.cover,
@ -83,7 +83,7 @@ class _ScoreViewDecoration extends StatelessWidget {
),
),
child: Padding(
padding: const EdgeInsets.all(boardWidth - 1),
padding: const EdgeInsets.all(borderWidth - 1),
child: ClipRRect(
borderRadius: radius,
child: child,

@ -28,6 +28,7 @@ class PlayButtonOverlay extends StatelessWidget {
context: context,
barrierDismissible: false,
builder: (_) {
// TODO(arturplaczek): remove after merge StarBlocListener
final height = MediaQuery.of(context).size.height * 0.5;
return Center(

@ -6,6 +6,7 @@ import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/select_character/select_character.dart';
import 'package:pinball/start_game/start_game.dart';
import 'package:pinball_theme/pinball_theme.dart';
import 'package:pinball_ui/pinball_ui.dart';
class CharacterSelectionDialog extends StatelessWidget {
const CharacterSelectionDialog({Key? key}) : super(key: key);
@ -32,25 +33,32 @@ class CharacterSelectionView extends StatelessWidget {
Widget build(BuildContext context) {
final l10n = context.l10n;
return Scaffold(
return PixelatedDecoration(
header: Text(
l10n.characterSelectionTitle,
style: Theme.of(context).textTheme.headline3,
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 80),
Text(
l10n.characterSelectionTitle,
style: Theme.of(context).textTheme.headline3,
),
const SizedBox(height: 80),
const _CharacterSelectionGridView(),
const SizedBox(height: 20),
TextButton(
onPressed: () {
Navigator.of(context).pop();
// TODO(arturplaczek): remove after merge StarBlocListener
final height = MediaQuery.of(context).size.height * 0.5;
showDialog<void>(
context: context,
builder: (_) => const HowToPlayDialog(),
builder: (_) => Center(
child: SizedBox(
height: height,
width: height * 1.4,
child: const HowToPlayDialog(),
),
),
);
},
child: Text(l10n.start),

@ -2,6 +2,7 @@
import 'package:flutter/material.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_ui/pinball_ui.dart';
class HowToPlayDialog extends StatelessWidget {
const HowToPlayDialog({Key? key}) : super(key: key);
@ -11,19 +12,15 @@ class HowToPlayDialog extends StatelessWidget {
final l10n = context.l10n;
const spacing = SizedBox(height: 16);
return Dialog(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(l10n.howToPlay),
spacing,
const _LaunchControls(),
spacing,
const _FlipperControls(),
],
),
return PixelatedDecoration(
header: Text(l10n.howToPlay),
body: ListView(
children: const [
spacing,
_LaunchControls(),
spacing,
_FlipperControls(),
],
),
);
}
@ -41,9 +38,7 @@ class _LaunchControls extends StatelessWidget {
children: [
Text(l10n.launchControls),
const SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
Wrap(
children: const [
KeyIndicator.fromIcon(keyIcon: Icons.keyboard_arrow_down),
spacing,
@ -81,9 +76,7 @@ class _FlipperControls extends StatelessWidget {
],
),
const SizedBox(height: 8),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
Wrap(
children: const [
KeyIndicator.fromKeyName(keyName: 'A'),
rowSpacing,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 37 KiB

@ -235,8 +235,10 @@ class $AssetsImagesSlingshotGen {
class $AssetsImagesSparkyGen {
const $AssetsImagesSparkyGen();
/// File path: assets/images/sparky/animatronic.png
AssetGenImage get animatronic =>
const AssetGenImage('assets/images/sparky/animatronic.png');
$AssetsImagesSparkyBumperGen get bumper =>
const $AssetsImagesSparkyBumperGen();
$AssetsImagesSparkyComputerGen get computer =>

@ -82,7 +82,7 @@ class Plunger extends BodyComponent with InitialPosition, Layered {
/// The velocity's magnitude depends on how far the [Plunger] has been pulled
/// from its original [initialPosition].
void release() {
final velocity = (initialPosition.y - body.position.y) * 5;
final velocity = (initialPosition.y - body.position.y) * 7;
body.linearVelocity = Vector2(0, velocity);
_spriteComponent.release();
}
@ -221,7 +221,7 @@ class PlungerAnchorPrismaticJointDef extends PrismaticJointDef {
plunger.body,
anchor.body,
plunger.body.position + anchor.body.position,
Vector2(18.6, BoardDimensions.bounds.height),
Vector2(16, BoardDimensions.bounds.height),
);
enableLimit = true;
lowerTranslation = double.negativeInfinity;

@ -55,7 +55,7 @@ abstract class RenderPriority {
static const int plunger = _above + launchRamp;
static const int rocket = _above + bottomBoundary;
static const int rocket = _below + bottomBoundary;
// Dino Land

@ -6,19 +6,22 @@ import 'package:pinball_components/pinball_components.dart' hide Assets;
/// A [SpriteComponent] for the rocket over [Plunger].
/// {@endtemplate}
class RocketSpriteComponent extends SpriteComponent with HasGameRef {
// TODO(ruimiguel): change this priority to be over launcher ramp and bottom
// wall.
/// {@macro rocket_sprite_component}
RocketSpriteComponent() : super(priority: RenderPriority.rocket);
RocketSpriteComponent()
: super(
priority: RenderPriority.rocket,
anchor: Anchor.center,
);
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(
Assets.images.plunger.rocket.keyName,
final sprite = Sprite(
gameRef.images.fromCache(
Assets.images.plunger.rocket.keyName,
),
);
this.sprite = sprite;
size = sprite.originalSize / 10;
anchor = Anchor.center;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 82 KiB

@ -8,14 +8,24 @@ import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart';
void main() {
group('RocketSpriteComponent', () {
final tester = FlameTester(TestGame.new);
TestWidgetsFlutterBinding.ensureInitialized();
final assets = [
Assets.images.plunger.rocket.keyName,
];
final flameTester = FlameTester(() => TestGame(assets));
tester.testGameWidget(
group('RocketSpriteComponent', () {
flameTester.testGameWidget(
'renders correctly',
setUp: (game, tester) async {
game.camera.followVector2(Vector2.zero());
await game.images.loadAll(assets);
await game.ensureAdd(RocketSpriteComponent());
game.camera
..followVector2(Vector2.zero())
..zoom = 8;
await tester.pump();
},
verify: (game, tester) async {
await expectLater(

@ -0,0 +1,39 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# VSCode related
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json

@ -0,0 +1,11 @@
# pinball_ui
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link]
[![License: MIT][license_badge]][license_link]
UI Toolkit for the Pinball Flutter Application
[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,4 @@
include: package:very_good_analysis/analysis_options.2.4.0.yaml
analyzer:
exclude:
- lib/**/*.gen.dart

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -0,0 +1,78 @@
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
// ignore_for_file: directives_ordering,unnecessary_import
import 'package:flutter/widgets.dart';
class $AssetsImagesGen {
const $AssetsImagesGen();
$AssetsImagesDialogGen get dialog => const $AssetsImagesDialogGen();
}
class $AssetsImagesDialogGen {
const $AssetsImagesDialogGen();
/// File path: assets/images/dialog/background.png
AssetGenImage get background =>
const AssetGenImage('assets/images/dialog/background.png');
}
class Assets {
Assets._();
static const $AssetsImagesGen images = $AssetsImagesGen();
}
class AssetGenImage extends AssetImage {
const AssetGenImage(String assetName)
: super(assetName, package: 'pinball_ui');
Image image({
Key? key,
ImageFrameBuilder? frameBuilder,
ImageLoadingBuilder? loadingBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? width,
double? height,
Color? color,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
FilterQuality filterQuality = FilterQuality.low,
}) {
return Image(
key: key,
image: this,
frameBuilder: frameBuilder,
loadingBuilder: loadingBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
width: width,
height: height,
color: color,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
filterQuality: filterQuality,
);
}
String get path => assetName;
}

@ -0,0 +1 @@
export 'assets.gen.dart';

@ -0,0 +1,3 @@
library pinball_ui;
export 'src/dialog/dialog.dart';

@ -0,0 +1 @@
export 'pixelated_decoration.dart';

@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:pinball_ui/gen/gen.dart';
/// {@template pixelated_decoration}
/// Widget with pixelated background and layout defined for dialog displays.
/// {@endtemplate}
class PixelatedDecoration extends StatelessWidget {
/// {@macro pixelated_decoration}
const PixelatedDecoration({
Key? key,
required Widget header,
required Widget body,
}) : _header = header,
_body = body,
super(key: key);
final Widget _header;
final Widget _body;
@override
Widget build(BuildContext context) {
const radius = BorderRadius.all(Radius.circular(12));
return Material(
borderRadius: radius,
child: Padding(
padding: const EdgeInsets.all(5),
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: radius,
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(Assets.images.dialog.background.keyName),
),
),
child: ClipRRect(
borderRadius: radius,
child: Column(
children: [
Expanded(
child: Center(
child: _header,
),
),
Expanded(
flex: 4,
child: _body,
),
],
),
),
),
),
);
}
}

@ -0,0 +1,29 @@
name: pinball_ui
description: UI Toolkit for the Pinball Flutter Application
version: 1.0.0+1
publish_to: none
environment:
sdk: ">=2.16.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
test: ^1.19.2
very_good_analysis: ^2.4.0
flutter:
uses-material-design: true
generate: true
assets:
- assets/images/dialog/
flutter_gen:
line_length: 80
assets:
package_parameter_enabled: true

@ -0,0 +1,26 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_ui/pinball_ui.dart';
void main() {
group('PixelatedDecoration', () {
testWidgets('renders header and body', (tester) async {
const headerText = 'header';
const bodyText = 'body';
await tester.pumpWidget(
MaterialApp(
home: PixelatedDecoration(
header: Text(headerText),
body: Text(bodyText),
),
),
);
expect(find.text(headerText), findsOneWidget);
expect(find.text(bodyText), findsOneWidget);
});
});
}

@ -499,6 +499,13 @@ packages:
relative: true
source: path
version: "1.0.0+1"
pinball_ui:
dependency: "direct main"
description:
path: "packages/pinball_ui"
relative: true
source: path
version: "1.0.0+1"
platform:
dependency: transitive
description:

@ -35,6 +35,8 @@ dependencies:
path: packages/pinball_flame
pinball_theme:
path: packages/pinball_theme
pinball_ui:
path: packages/pinball_ui
dev_dependencies:
bloc_test: ^9.0.2

@ -2,16 +2,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/start_game/start_game.dart';
import '../../helpers/helpers.dart';
void main() {
group('HowToPlayDialog', () {
testWidgets('displays dialog', (tester) async {
testWidgets('displays content', (tester) async {
final l10n = await AppLocalizations.delegate.load(Locale('en'));
await tester.pumpApp(HowToPlayDialog());
expect(find.byType(Dialog), findsOneWidget);
expect(find.text(l10n.launchControls), findsOneWidget);
});
});

Loading…
Cancel
Save