diff --git a/CHANGELOG.md b/CHANGELOG.md index fc9fb75e3..2d65cbfb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # CHANGELOG ## [next] + - Option for overlays to be already visible on the GameWidget + - Adding game to the overlay builder - Rename retreive -> Retrieve - Use internal children set in BaseComponent (fixes issue adding multiple children) - Remove develop branches from github workflow definition diff --git a/doc/examples/with_widgets_overlay/lib/example_game.dart b/doc/examples/with_widgets_overlay/lib/example_game.dart index 463a78a51..a02324067 100644 --- a/doc/examples/with_widgets_overlay/lib/example_game.dart +++ b/doc/examples/with_widgets_overlay/lib/example_game.dart @@ -5,8 +5,6 @@ import 'package:flame/palette.dart'; import 'package:flutter/material.dart'; class ExampleGame extends Game with TapDetector { - bool isPaused = false; - @override void update(double dt) {} @@ -25,14 +23,10 @@ class ExampleGame extends Game with TapDetector { @override void onTap() { - if (isPaused) { + if (overlays.isActive('PauseMenu')) { overlays.remove('PauseMenu'); - isPaused = false; } else { - overlays.add( - 'PauseMenu', - ); - isPaused = true; + overlays.add('PauseMenu'); } } } diff --git a/doc/examples/with_widgets_overlay/lib/main.dart b/doc/examples/with_widgets_overlay/lib/main.dart index 01fb8df50..175bf2adf 100644 --- a/doc/examples/with_widgets_overlay/lib/main.dart +++ b/doc/examples/with_widgets_overlay/lib/main.dart @@ -26,7 +26,7 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { ExampleGame _myGame; - Widget pauseMenuBuilder(BuildContext buildContext) { + Widget pauseMenuBuilder(BuildContext buildContext, ExampleGame game) { return Center( child: Container( width: 100, @@ -52,6 +52,7 @@ class _MyHomePageState extends State { overlayBuilderMap: { "PauseMenu": pauseMenuBuilder, }, + initialActiveOverlays: const ['PauseMenu'], ), floatingActionButton: FloatingActionButton( onPressed: () => newGame(), diff --git a/lib/game/game.dart b/lib/game/game.dart index 02018e410..d22f1603d 100644 --- a/lib/game/game.dart +++ b/lib/game/game.dart @@ -191,4 +191,7 @@ class ActiveOverlaysNotifier extends ChangeNotifier { /// A [Set] of the active overlay names. Set get value => _activeOverlays; + + /// Returns if the given [overlayName] is active + bool isActive(String overlayName) => _activeOverlays.contains(overlayName); } diff --git a/lib/game/game_widget.dart b/lib/game/game_widget.dart index 34f548cd7..1e1b8b8cc 100644 --- a/lib/game/game_widget.dart +++ b/lib/game/game_widget.dart @@ -14,6 +14,11 @@ typedef GameLoadingWidgetBuilder = Widget Function( bool error, ); +typedef OverlayWidgetBuilder = Widget Function( + BuildContext context, + T game, +); + /// A [StatefulWidget] that is in charge of attaching a [Game] instance into the flutter tree /// class GameWidget extends StatefulWidget { @@ -36,7 +41,15 @@ class GameWidget extends StatefulWidget { /// See also: /// - [new GameWidget] /// - [Game.overlays] - final Map overlayBuilderMap; + final Map> overlayBuilderMap; + + /// A List of the initially active overlays, this is used only on the first build of the widget. + /// To control the overlays that are active use [Game.overlays] + /// + /// See also: + /// - [new GameWidget] + /// - [Game.overlays] + final List initialActiveOverlays; /// Renders a [game] in a flutter widget tree. /// @@ -82,6 +95,7 @@ class GameWidget extends StatefulWidget { this.loadingBuilder, this.backgroundBuilder, this.overlayBuilderMap, + this.initialActiveOverlays, }) : super(key: key); /// Renders a [game] in a flutter widget tree alongside widgets overlays. @@ -89,11 +103,11 @@ class GameWidget extends StatefulWidget { /// To use overlays, the game subclass has to be mixed with [HasWidgetsOverlay], @override - _GameWidgetState createState() => _GameWidgetState(); + _GameWidgetState createState() => _GameWidgetState(); } -class _GameWidgetState extends State { - Set activeOverlays = {}; +class _GameWidgetState extends State> { + Set initialActiveOverlays; Future _gameLoaderFuture; Future get _gameLoaderFutureCache => @@ -102,14 +116,30 @@ class _GameWidgetState extends State { @override void initState() { super.initState(); + + // Add the initial overlays + _initActiveOverlays(); + addOverlaysListener(widget.game); } + void _initActiveOverlays() { + if (widget.initialActiveOverlays != null) { + _checkOverlays(widget.initialActiveOverlays.toSet()); + widget.initialActiveOverlays.forEach((key) { + widget.game.overlays.add(key); + }); + } + } + @override - void didUpdateWidget(covariant GameWidget oldWidget) { + void didUpdateWidget(GameWidget oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.game != widget.game) { removeOverlaysListener(oldWidget.game); + + // Reset the overlays + _initActiveOverlays(); addOverlaysListener(widget.game); // Reset the loader future @@ -124,22 +154,26 @@ class _GameWidgetState extends State { } // widget overlay stuff - void addOverlaysListener(Game game) { + void addOverlaysListener(T game) { widget.game.overlays.addListener(onChangeActiveOverlays); - activeOverlays = widget.game.overlays.value; + initialActiveOverlays = widget.game.overlays.value; } - void removeOverlaysListener(Game game) { + void removeOverlaysListener(T game) { game.overlays.removeListener(onChangeActiveOverlays); } - void onChangeActiveOverlays() { - widget.game.overlays.value.forEach((overlayKey) { + void _checkOverlays(Set overlays) { + overlays.forEach((overlayKey) { assert(widget.overlayBuilderMap.containsKey(overlayKey), "A non mapped overlay has been added: $overlayKey"); }); + } + + void onChangeActiveOverlays() { + _checkOverlays(widget.game.overlays.value); setState(() { - activeOverlays = widget.game.overlays.value; + initialActiveOverlays = widget.game.overlays.value; }); } @@ -224,11 +258,11 @@ class _GameWidgetState extends State { if (widget.overlayBuilderMap == null) { return stackWidgets; } - final widgets = activeOverlays.map((String overlayKey) { + final widgets = initialActiveOverlays.map((String overlayKey) { final builder = widget.overlayBuilderMap[overlayKey]; return KeyedSubtree( key: ValueKey(overlayKey), - child: builder(context), + child: builder(context, widget.game), ); }); stackWidgets.addAll(widgets);