diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fe5a33ee..fd9bad552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Creating new way of loading animations and sprites - Dragable mixin for components - Fix update+render of component children + - Moving size to Game instead of BaseGame ## 1.0.0-rc2 - Improve IsometricTileMap and Spritesheet classes diff --git a/doc/examples/animations/lib/main.dart b/doc/examples/animations/lib/main.dart index 8e8dbd548..6d7db1814 100644 --- a/doc/examples/animations/lib/main.dart +++ b/doc/examples/animations/lib/main.dart @@ -1,7 +1,6 @@ import 'package:flame/game.dart'; import 'package:flame/gestures.dart'; import 'package:flutter/gestures.dart'; -import 'package:flame/flame.dart'; import 'package:flame/extensions/vector2.dart'; import 'package:flame/sprite_animation.dart'; import 'package:flame/components/sprite_animation_component.dart'; @@ -11,8 +10,7 @@ import 'dart:ui'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final Vector2 size = await Flame.util.initialDimensions(); - final game = MyGame(size); + final game = MyGame(); runApp( GameWidget( game: game, @@ -81,8 +79,4 @@ class MyGame extends BaseGame with TapDetector { void onTapDown(TapDownDetails evt) { addAnimation(Vector2(evt.globalPosition.dx, evt.globalPosition.dy)); } - - MyGame(Vector2 screenSize) { - size.setFrom(screenSize); - } } diff --git a/doc/examples/aseprite/lib/main.dart b/doc/examples/aseprite/lib/main.dart index 83a6c000d..9dfa1d8b7 100644 --- a/doc/examples/aseprite/lib/main.dart +++ b/doc/examples/aseprite/lib/main.dart @@ -1,4 +1,3 @@ -import 'package:flame/flame.dart'; import 'package:flame/game.dart'; import 'package:flame/sprite_animation.dart'; import 'package:flame/extensions/vector2.dart'; @@ -6,20 +5,14 @@ import 'package:flame/components/sprite_animation_component.dart'; import 'package:flutter/material.dart'; void main() async { - WidgetsFlutterBinding.ensureInitialized(); - final Vector2 size = await Flame.util.initialDimensions(); runApp( GameWidget( - game: MyGame(size), + game: MyGame(), ), ); } class MyGame extends BaseGame { - MyGame(Vector2 screenSize) { - size = screenSize; - } - @override Future onLoad() async { final image = await images.load('chopper.png'); diff --git a/doc/examples/nine_tile_box/lib/main.dart b/doc/examples/nine_tile_box/lib/main.dart index b2d345280..15b89c053 100644 --- a/doc/examples/nine_tile_box/lib/main.dart +++ b/doc/examples/nine_tile_box/lib/main.dart @@ -1,5 +1,4 @@ import 'package:flame/game.dart'; -import 'package:flame/flame.dart'; import 'package:flame/nine_tile_box.dart'; import 'package:flame/sprite.dart'; import 'package:flame/extensions/vector2.dart'; @@ -8,9 +7,8 @@ import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final size = await Flame.util.initialDimensions(); - final game = MyGame(size); + final game = MyGame(); runApp( GameWidget( game: game, @@ -19,11 +17,8 @@ void main() async { } class MyGame extends Game { - Vector2 size; NineTileBox nineTileBox; - MyGame(this.size); - @override Future onLoad() async { final sprite = Sprite(await images.load('nine-box.png')); diff --git a/doc/examples/render_flip/lib/main.dart b/doc/examples/render_flip/lib/main.dart index 3b1695269..55b462a4d 100644 --- a/doc/examples/render_flip/lib/main.dart +++ b/doc/examples/render_flip/lib/main.dart @@ -1,6 +1,5 @@ import 'package:flame/sprite_animation.dart'; import 'package:flame/components/sprite_animation_component.dart'; -import 'package:flame/flame.dart'; import 'package:flame/game.dart'; import 'package:flame/extensions/vector2.dart'; import 'package:flutter/material.dart' hide Image; @@ -8,8 +7,7 @@ import 'dart:ui'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final Vector2 size = await Flame.util.initialDimensions(); - final game = MyGame(size); + final game = MyGame(); runApp( GameWidget( game: game, @@ -56,8 +54,4 @@ class MyGame extends BaseGame { ), ); } - - MyGame(Vector2 screenSize) { - size.setFrom(screenSize); - } } diff --git a/doc/examples/sprite_batch/lib/main.dart b/doc/examples/sprite_batch/lib/main.dart index fa4faa1cb..6b4abd0fa 100644 --- a/doc/examples/sprite_batch/lib/main.dart +++ b/doc/examples/sprite_batch/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:math'; -import 'package:flame/flame.dart'; import 'package:flutter/material.dart'; import 'package:flame/game.dart'; import 'package:flame/sprite_batch.dart'; @@ -9,8 +8,7 @@ import 'package:flame/components/sprite_batch_component.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final Vector2 size = await Flame.util.initialDimensions(); - final game = MyGame(size); + final game = MyGame(); runApp( GameWidget( game: game, @@ -21,13 +19,8 @@ void main() async { class MyGame extends BaseGame { SpriteBatch spriteBatch; - MyGame(Vector2 screenSize) { - size = screenSize; - - initData(); - } - - void initData() async { + @override + Future onLoad() async { spriteBatch = await SpriteBatch.withAsset('boom3.png'); spriteBatch.add( diff --git a/doc/examples/sprites/lib/main.dart b/doc/examples/sprites/lib/main.dart index b18a2d180..de5ce9d77 100644 --- a/doc/examples/sprites/lib/main.dart +++ b/doc/examples/sprites/lib/main.dart @@ -1,15 +1,13 @@ import 'dart:math'; import 'package:flame/components/sprite_component.dart'; -import 'package:flame/flame.dart'; import 'package:flame/game.dart'; import 'package:flame/extensions/vector2.dart'; import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final Vector2 size = await Flame.util.initialDimensions(); - final game = MyGame(size); + final game = MyGame(); runApp( GameWidget( game: game, @@ -18,10 +16,6 @@ void main() async { } class MyGame extends BaseGame { - MyGame(Vector2 screenSize) { - size = screenSize; - } - @override Future onLoad() async { final r = Random(); diff --git a/doc/examples/text/lib/main.dart b/doc/examples/text/lib/main.dart index 2792c479a..45264e531 100644 --- a/doc/examples/text/lib/main.dart +++ b/doc/examples/text/lib/main.dart @@ -3,18 +3,16 @@ import 'dart:ui'; import 'package:flame/anchor.dart'; import 'package:flame/components/text_box_component.dart'; import 'package:flame/components/text_component.dart'; -import 'package:flame/flame.dart'; import 'package:flame/game.dart'; import 'package:flame/palette.dart'; import 'package:flame/text_config.dart'; import 'package:flame/extensions/vector2.dart'; import 'package:flutter/material.dart'; -void main() async { - final Vector2 size = await Flame.util.initialDimensions(); +void main() { runApp( GameWidget( - game: MyGame(size), + game: MyGame(), ), ); } @@ -54,8 +52,8 @@ class MyTextBox extends TextBoxComponent { } class MyGame extends BaseGame { - MyGame(Vector2 screenSize) { - size = screenSize; + @override + Future onLoad() async { add(TextComponent('Hello, Flame', config: regular) ..anchor = Anchor.topCenter ..x = size.x / 2 diff --git a/doc/examples/with_widgets_overlay/lib/example_game.dart b/doc/examples/with_widgets_overlay/lib/example_game.dart index 9f0ed08b5..463a78a51 100644 --- a/doc/examples/with_widgets_overlay/lib/example_game.dart +++ b/doc/examples/with_widgets_overlay/lib/example_game.dart @@ -10,6 +10,11 @@ class ExampleGame extends Game with TapDetector { @override void update(double dt) {} + @override + Future onLoad() async { + print('game loaded'); + } + @override void render(Canvas canvas) { canvas.drawRect( diff --git a/lib/game/base_game.dart b/lib/game/base_game.dart index c9f66ad1a..1d12acb53 100644 --- a/lib/game/base_game.dart +++ b/lib/game/base_game.dart @@ -31,10 +31,6 @@ class BaseGame extends Game with FPSCounter { /// Components to be removed on the next update final Set _removeLater = {}; - /// Current game viewport size, updated every resize via the [resize] method hook - final Vector2 size = Vector2.zero(); - set size(Vector2 size) => this.size.setFrom(size); - /// Camera position; every non-HUD component is translated so that the camera position is the top-left corner of the screen. Vector2 camera = Vector2.zero(); @@ -142,7 +138,7 @@ class BaseGame extends Game with FPSCounter { @override @mustCallSuper void onResize(Vector2 size) { - this.size.setFrom(size); + super.onResize(size); components.forEach((c) => c.onGameResize(size)); } diff --git a/lib/game/game.dart b/lib/game/game.dart index 51f890524..02018e410 100644 --- a/lib/game/game.dart +++ b/lib/game/game.dart @@ -23,6 +23,9 @@ abstract class Game { final assets = AssetsCache(); BuildContext buildContext; + /// Current game viewport size, updated every resize via the [resize] method hook + final Vector2 size = Vector2.zero(); + bool get isAttached => buildContext != null; /// Returns the game background color. @@ -40,8 +43,11 @@ abstract class Game { /// This is the resize hook; every time the game widget is resized, this hook is called. /// - /// The default implementation does nothing; override to use the hook. - void onResize(Vector2 size) {} + /// The default implementation just sets the new size on the size field + @mustCallSuper + void onResize(Vector2 size) { + this.size.setFrom(size); + } /// This is the lifecycle state change hook; every time the game is resumed, paused or suspended, this is called. /// diff --git a/lib/game/game_widget.dart b/lib/game/game_widget.dart index 0724e8ed1..4aec4634a 100644 --- a/lib/game/game_widget.dart +++ b/lib/game/game_widget.dart @@ -6,6 +6,7 @@ import 'game.dart'; import '../gestures.dart'; import '../components/mixins/dragable.dart'; import '../components/mixins/tapable.dart'; +import '../extensions/size.dart'; import 'game_render_box.dart'; typedef GameLoadingWidgetBuilder = Widget Function( @@ -94,11 +95,14 @@ class GameWidget extends StatefulWidget { class _GameWidgetState extends State { Set activeOverlays = {}; + Future _gameLoaderFuture; + Future get _memoizedGameLoaderFuture => + _gameLoaderFuture ?? (_gameLoaderFuture = widget.game.onLoad()); + @override void initState() { super.initState(); addOverlaysListener(widget.game); - loadingFuture = widget.game.onLoad(); } @override @@ -107,8 +111,10 @@ class _GameWidgetState extends State { if (oldWidget.game != widget.game) { removeOverlaysListener(oldWidget.game); addOverlaysListener(widget.game); + + // Reset the loader future + _gameLoaderFuture = null; } - loadingFuture = widget.game.onLoad(); } @override @@ -137,9 +143,6 @@ class _GameWidgetState extends State { }); } - // loading future - Future loadingFuture; - @override Widget build(BuildContext context) { Widget internalGameWidget = _GameRenderObjectWidget(widget.game); @@ -177,21 +180,29 @@ class _GameWidgetState extends State { final stackedWidgets = [internalGameWidget]; _addBackground(context, stackedWidgets); _addOverlays(context, stackedWidgets); + + final textDir = widget.textDirection ?? + Directionality.maybeOf(context) ?? + TextDirection.ltr; + return Directionality( - textDirection: widget.textDirection ?? - Directionality.maybeOf(context) ?? - TextDirection.ltr, + textDirection: textDir, child: Container( color: widget.game.backgroundColor(), - child: FutureBuilder( - future: loadingFuture, - builder: (_, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return Stack(children: stackedWidgets); - } - return widget.loadingBuilder != null - ? widget.loadingBuilder(context, snapshot.hasError) - : Container(); + child: LayoutBuilder( + builder: (_, BoxConstraints constraints) { + widget.game.onResize(constraints.biggest.toVector2()); + return FutureBuilder( + future: _memoizedGameLoaderFuture, + builder: (_, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return Stack(children: stackedWidgets); + } + return widget.loadingBuilder != null + ? widget.loadingBuilder(context, snapshot.hasError) + : Container(); + }, + ); }, ), ),