Merge branch 'main' into feat/paths

pull/14/head
RuiAlonso 4 years ago
commit 5bff54f3d8

@ -0,0 +1,18 @@
name: pinball_theme
on:
push:
paths:
- "packages/pinball_theme/**"
- ".github/workflows/pinball_theme.yaml"
pull_request:
paths:
- "packages/pinball_theme/**"
- ".github/workflows/pinball_theme.yaml"
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
working_directory: packages/pinball_theme

2
.gitignore vendored

@ -125,3 +125,5 @@ app.*.map.json
!.idea/codeStyles/
!.idea/dictionaries/
!.idea/runConfigurations/
.firebase

@ -154,6 +154,33 @@ Update the `CFBundleLocalizations` array in the `Info.plist` at `ios/Runner/Info
}
```
### Deploy application to Firebase hosting
Follow the following steps to deploy the application.
## Firebase CLI
Install and authenticate with [Firebase CLI tools](https://firebase.google.com/docs/cli)
## Build the project using the desired environment
```bash
# Development
$ flutter build web --release --target lib/main_development.dart
# Staging
$ flutter build web --release --target lib/main_staging.dart
# Production
$ flutter build web --release --target lib/main_production.dart
```
## Deploy
```bash
$ firebase deploy
```
[coverage_badge]: coverage_badge.svg
[flutter_localizations_link]: https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html
[internationalization_link]: https://flutter.dev/docs/development/accessibility-and-localization/internationalization

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@ -0,0 +1,11 @@
{
"hosting": {
"public": "build/web",
"site": "ashehwkdkdjruejdnensjsjdne",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}

@ -1,23 +1,31 @@
import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/body_component.dart';
import 'package:flutter/material.dart';
import 'package:forge2d/forge2d.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
class Ball extends BodyComponent<PinballGame>
class Ball extends PositionBodyComponent<PinballGame, SpriteComponent>
with BlocComponent<GameBloc, GameState> {
Ball({
required Vector2 position,
}) : _position = position {
// TODO(alestiago): Use asset instead of color when provided.
paint = Paint()..color = const Color(0xFFFFFFFF);
}
}) : _position = position,
super(size: ballSize);
static final ballSize = Vector2.all(2);
final Vector2 _position;
static const spritePath = 'components/ball.png';
@override
Future<void> onLoad() async {
await super.onLoad();
final sprite = await gameRef.loadSprite(spritePath);
positionComponent = SpriteComponent(sprite: sprite, size: ballSize);
}
@override
Body createBody() {
final shape = CircleShape()..radius = 2;
final shape = CircleShape()..radius = ballSize.x / 2;
final fixtureDef = FixtureDef(shape)..density = 1;

@ -3,6 +3,9 @@
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/components/components.dart';
/// {@template wall}
/// A continuos generic and [BodyType.static] barrier that divides a game area.
/// {@endtemplate}
class Wall extends BodyComponent {
Wall({
required this.start,
@ -29,6 +32,12 @@ class Wall extends BodyComponent {
}
}
/// {@template bottom_wall}
/// [Wall] located at the bottom of the board.
///
/// Collisions with [BottomWall] are listened by
/// [BottomWallBallContactCallback].
/// {@endtemplate}
class BottomWall extends Wall {
BottomWall(Forge2DGame game)
: super(
@ -40,6 +49,9 @@ class BottomWall extends Wall {
);
}
/// {@template bottom_wall_ball_contact_callback}
/// Listens when a [Ball] falls into a [BottomWall].
/// {@endtemplate}
class BottomWallBallContactCallback extends ContactCallback<Ball, BottomWall> {
@override
void begin(Ball ball, BottomWall wall, Contact contact) {

@ -1,4 +1,5 @@
export 'bloc/game_bloc.dart';
export 'components/components.dart';
export 'game_assets.dart';
export 'pinball_game.dart';
export 'view/view.dart';

@ -0,0 +1,11 @@
import 'package:pinball/game/game.dart';
/// Add methods to help loading and caching game assets.
extension PinballGameAssetsX on PinballGame {
/// Pre load the initial assets of the game.
Future<void> preLoadAssets() async {
await Future.wait([
images.load(Ball.spritePath),
]);
}
}

@ -1,10 +1,14 @@
import 'dart:async';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/game.dart';
class PinballGame extends Forge2DGame with FlameBloc {
void spawnBall() {
add(Ball(position: ballStartingPosition));
add(
Ball(position: ballStartingPosition),
);
}
// TODO(erickzanardo): Change to the plumber position
@ -18,10 +22,15 @@ class PinballGame extends Forge2DGame with FlameBloc {
@override
Future<void> onLoad() async {
spawnBall();
addContactCallback(BallScorePointsCallback());
await add(BottomWall(this));
addContactCallback(BottomWallBallContactCallback());
}
@override
void onAttach() {
super.onAttach();
spawnBall();
}
}

@ -23,9 +23,26 @@ class PinballGamePage extends StatelessWidget {
}
}
class PinballGameView extends StatelessWidget {
class PinballGameView extends StatefulWidget {
const PinballGameView({Key? key}) : super(key: key);
@override
State<PinballGameView> createState() => _PinballGameViewState();
}
class _PinballGameViewState extends State<PinballGameView> {
late PinballGame _game;
@override
void initState() {
super.initState();
// TODO(erickzanardo): Revisit this when we start to have more assets
// this could expose a Stream (maybe even a cubit?) so we could show the
// the loading progress with some fancy widgets.
_game = PinballGame()..preLoadAssets();
}
@override
Widget build(BuildContext context) {
return BlocListener<GameBloc, GameState>(
@ -39,7 +56,7 @@ class PinballGameView extends StatelessWidget {
);
}
},
child: GameWidget<PinballGame>(game: PinballGame()),
child: GameWidget<PinballGame>(game: _game),
);
}
}

@ -0,0 +1,13 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:pinball_theme/pinball_theme.dart';
part 'theme_state.dart';
class ThemeCubit extends Cubit<ThemeState> {
ThemeCubit() : super(const ThemeState.initial());
void characterSelected(CharacterTheme characterTheme) {
emit(ThemeState(PinballTheme(characterTheme: characterTheme)));
}
}

@ -0,0 +1,13 @@
part of 'theme_cubit.dart';
class ThemeState extends Equatable {
const ThemeState(this.theme);
const ThemeState.initial()
: theme = const PinballTheme(characterTheme: DashTheme());
final PinballTheme theme;
@override
List<Object> get props => [theme];
}

@ -0,0 +1 @@
export 'cubit/theme_cubit.dart';

@ -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_theme
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link]
[![License: MIT][license_badge]][license_link]
Package containing themes for pinball game.
[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,4 @@
library pinball_theme;
export 'src/pinball_theme.dart';
export 'src/themes/themes.dart';

@ -0,0 +1,23 @@
import 'package:equatable/equatable.dart';
import 'package:pinball_theme/pinball_theme.dart';
/// {@template pinball_theme}
/// Defines all theme assets and attributes.
///
/// Game components should have a getter specified here to load their
/// corresponding assets for the game.
/// {@endtemplate}
class PinballTheme extends Equatable {
/// {@macro pinball_theme}
const PinballTheme({
required CharacterTheme characterTheme,
}) : _characterTheme = characterTheme;
final CharacterTheme _characterTheme;
/// [CharacterTheme] for the chosen character.
CharacterTheme get characterTheme => _characterTheme;
@override
List<Object?> get props => [_characterTheme];
}

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:pinball_theme/pinball_theme.dart';
/// {@template android_theme}
/// Defines Android character theme assets and attributes.
/// {@endtemplate}
class AndroidTheme extends CharacterTheme {
/// {@macro android_theme}
const AndroidTheme();
@override
Color get ballColor => Colors.green;
}

@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
/// {@template character_theme}
/// Base class for creating character themes.
///
/// Character specific game components should have a getter specified here to
/// load their corresponding assets for the game.
/// {@endtemplate}
abstract class CharacterTheme extends Equatable {
/// {@macro character_theme}
const CharacterTheme();
/// Ball color for this theme.
Color get ballColor;
@override
List<Object?> get props => [ballColor];
}

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:pinball_theme/pinball_theme.dart';
/// {@template dash_theme}
/// Defines Dash character theme assets and attributes.
/// {@endtemplate}
class DashTheme extends CharacterTheme {
/// {@macro dash_theme}
const DashTheme();
@override
Color get ballColor => Colors.blue;
}

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:pinball_theme/pinball_theme.dart';
/// {@template dino_theme}
/// Defines Dino character theme assets and attributes.
/// {@endtemplate}
class DinoTheme extends CharacterTheme {
/// {@macro dino_theme}
const DinoTheme();
@override
Color get ballColor => Colors.grey;
}

@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:pinball_theme/pinball_theme.dart';
/// {@template sparky_theme}
/// Defines Sparky character theme assets and attributes.
/// {@endtemplate}
class SparkyTheme extends CharacterTheme {
/// {@macro sparky_theme}
const SparkyTheme();
@override
Color get ballColor => Colors.orange;
}

@ -0,0 +1,5 @@
export 'android_theme.dart';
export 'character_theme.dart';
export 'dash_theme.dart';
export 'dino_theme.dart';
export 'sparky_theme.dart';

@ -0,0 +1,17 @@
name: pinball_theme
description: Package containing themes for pinball game.
version: 1.0.0+1
publish_to: none
environment:
sdk: ">=2.16.0 <3.0.0"
dependencies:
equatable: ^2.0.3
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
very_good_analysis: ^2.4.0

@ -0,0 +1,28 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('PinballTheme', () {
const characterTheme = SparkyTheme();
test('can be instantiated', () {
expect(PinballTheme(characterTheme: characterTheme), isNotNull);
});
test('supports value equality', () {
expect(
PinballTheme(characterTheme: characterTheme),
equals(PinballTheme(characterTheme: characterTheme)),
);
});
test('characterTheme is correct', () {
expect(
PinballTheme(characterTheme: characterTheme).characterTheme,
equals(characterTheme),
);
});
});
}

@ -0,0 +1,21 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('AndroidTheme', () {
test('can be instantiated', () {
expect(AndroidTheme(), isNotNull);
});
test('supports value equality', () {
expect(AndroidTheme(), equals(AndroidTheme()));
});
test('ballColor is correct', () {
expect(AndroidTheme().ballColor, equals(Colors.green));
});
});
}

@ -0,0 +1,21 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('DashTheme', () {
test('can be instantiated', () {
expect(DashTheme(), isNotNull);
});
test('supports value equality', () {
expect(DashTheme(), equals(DashTheme()));
});
test('ballColor is correct', () {
expect(DashTheme().ballColor, equals(Colors.blue));
});
});
}

@ -0,0 +1,21 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('DinoTheme', () {
test('can be instantiated', () {
expect(DinoTheme(), isNotNull);
});
test('supports value equality', () {
expect(DinoTheme(), equals(DinoTheme()));
});
test('ballColor is correct', () {
expect(DinoTheme().ballColor, equals(Colors.grey));
});
});
}

@ -0,0 +1,21 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('SparkyTheme', () {
test('can be instantiated', () {
expect(SparkyTheme(), isNotNull);
});
test('supports value equality', () {
expect(SparkyTheme(), equals(SparkyTheme()));
});
test('ballColor is correct', () {
expect(SparkyTheme().ballColor, equals(Colors.orange));
});
});
}

@ -140,21 +140,21 @@ packages:
name: flame
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-releasecandidate.1"
version: "1.1.0-releasecandidate.2"
flame_bloc:
dependency: "direct main"
description:
name: flame_bloc
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-releasecandidate.1"
version: "1.2.0-releasecandidate.2"
flame_forge2d:
dependency: "direct main"
description:
name: flame_forge2d
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0-releasecandidate.1"
version: "0.9.0-releasecandidate.2"
flame_test:
dependency: "direct dev"
description:
@ -331,6 +331,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
pinball_theme:
dependency: "direct main"
description:
path: "packages/pinball_theme"
relative: true
source: path
version: "1.0.0+1"
pool:
dependency: transitive
description:

@ -9,9 +9,9 @@ environment:
dependencies:
bloc: ^8.0.2
equatable: ^2.0.3
flame: ^1.1.0-releasecandidate.1
flame_bloc: ^1.2.0-releasecandidate.1
flame_forge2d: ^0.9.0-releasecandidate.1
flame: ^1.1.0-releasecandidate.2
flame_bloc: ^1.2.0-releasecandidate.2
flame_forge2d: ^0.9.0-releasecandidate.2
flutter:
sdk: flutter
flutter_bloc: ^8.0.1
@ -20,6 +20,8 @@ dependencies:
geometry:
path: packages/geometry
intl: ^0.17.0
pinball_theme:
path: packages/pinball_theme
dev_dependencies:
bloc_test: ^9.0.2
@ -33,3 +35,6 @@ dev_dependencies:
flutter:
uses-material-design: true
generate: true
assets:
- assets/images/components/

@ -79,7 +79,7 @@ void main() {
final fixture = ball.body.fixtures[0];
expect(fixture.shape.shapeType, equals(ShapeType.circle));
expect(fixture.shape.radius, equals(2));
expect(fixture.shape.radius, equals(1));
},
);
});

@ -0,0 +1,22 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/theme/theme.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('ThemeCubit', () {
test('initial state has Dash character theme', () {
final themeCubit = ThemeCubit();
expect(themeCubit.state.theme.characterTheme, equals(const DashTheme()));
});
blocTest<ThemeCubit, ThemeState>(
'charcterSelected emits selected character theme',
build: ThemeCubit.new,
act: (bloc) => bloc.characterSelected(const SparkyTheme()),
expect: () => [
const ThemeState(PinballTheme(characterTheme: SparkyTheme())),
],
);
});
}

@ -0,0 +1,19 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/theme/theme.dart';
void main() {
group('ThemeState', () {
test('can be instantiated', () {
expect(const ThemeState.initial(), isNotNull);
});
test('supports value equality', () {
expect(
ThemeState.initial(),
equals(const ThemeState.initial()),
);
});
});
}
Loading…
Cancel
Save