diff --git a/assets/images/components/ball.png b/assets/images/components/ball.png new file mode 100644 index 00000000..af80811b Binary files /dev/null and b/assets/images/components/ball.png differ diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index e285b14b..2d9dddf0 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -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 +class Ball extends PositionBodyComponent with BlocComponent { 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 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; diff --git a/lib/game/game.dart b/lib/game/game.dart index 253dcc9f..ad02533d 100644 --- a/lib/game/game.dart +++ b/lib/game/game.dart @@ -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'; diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart new file mode 100644 index 00000000..964aeda1 --- /dev/null +++ b/lib/game/game_assets.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 preLoadAssets() async { + await Future.wait([ + images.load(Ball.spritePath), + ]); + } +} diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 11a9f546..ab2e0786 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -7,6 +7,7 @@ import 'package:pinball/game/game.dart'; class PinballGame extends Forge2DGame with FlameBloc, HasKeyboardHandlerComponents { + // TODO(erickzanardo): Change to the plumber position late final ballStartingPosition = screenToWorld( Vector2( diff --git a/lib/game/view/pinball_game_page.dart b/lib/game/view/pinball_game_page.dart index 28834907..02f5b34c 100644 --- a/lib/game/view/pinball_game_page.dart +++ b/lib/game/view/pinball_game_page.dart @@ -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 createState() => _PinballGameViewState(); +} + +class _PinballGameViewState extends State { + 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( @@ -39,7 +56,7 @@ class PinballGameView extends StatelessWidget { ); } }, - child: GameWidget(game: PinballGame()), + child: GameWidget(game: _game), ); } } diff --git a/pubspec.lock b/pubspec.lock index 7bf08da4..861dae5b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index 6c3bd98e..8738f2bb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 @@ -33,3 +33,6 @@ dev_dependencies: flutter: uses-material-design: true generate: true + + assets: + - assets/images/components/ diff --git a/test/game/components/ball_test.dart b/test/game/components/ball_test.dart index b32d16d5..7ac3ceff 100644 --- a/test/game/components/ball_test.dart +++ b/test/game/components/ball_test.dart @@ -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)); }, ); });