diff --git a/doc/flame/camera_and_viewport.md b/doc/flame/camera_and_viewport.md index 46b0a5cb7..a58d042ec 100644 --- a/doc/flame/camera_and_viewport.md +++ b/doc/flame/camera_and_viewport.md @@ -138,7 +138,7 @@ class MyGame extends FlameGame { anchor: Anchor.center, ); add(player); - + camera.followComponent(player); } } @@ -148,17 +148,20 @@ class MyGame extends FlameGame { ### Using the camera with the Game class If you are not using `FlameGame`, but instead are using the `Game` mixin, then you need to manage -calling certain camera methods yourself. Let's say we have the following game structure, and we +calling certain camera methods yourself. Let's say we have the following game structure, and we want to add the camera functionality: ```dart -class YourGame with Game { +class YourGame extends Game { Camera? camera; + @override Future onLoad() async {} + @override void render(Canvas canvas) {} + @override void update(double dt) {} } ``` @@ -166,8 +169,7 @@ class YourGame with Game { We first create a new camera instance on load and assign our game as the reference: ```dart - // ... - + @override Future onLoad() async { camera = Camera(); @@ -179,51 +181,42 @@ We first create a new camera instance on load and assign our game as the referen // Rest of your on load code. } - - // ... ``` -The camera can also be made aware of which position to follow, this is an optional feature as you -can also use the camare for just moving,snapping or shaking. +The camera can also be made aware of which position to follow, this is an optional feature as you +can also use the camera for just moving,snapping or shaking. -To do this the `Camera` class provides multiple methods for it but let's showcase the simplest one +To do this the `Camera` class provides multiple methods for it but let's showcase the simplest one and that is the `followVector2`: ```dart - // Somewhere in your code. - + // Somewhere in your code: camera?.followVector2( yourPositionToFollow, worldBounds: yourWorldBounds, // Optional to pass, it will overwrite the previous bounds. ); ``` -Now that the camera is created and it is aware of both the world bounds and the position it should +Now that the camera is created and it is aware of both the world bounds and the position it should follow, it can be used to translate the canvas in the render method: ```dart - // ... - + @override void render(Canvas canvas) { camera?.apply(canvas); // This will apply the camera transformation. // Rest of your rendering code. } - - // ... ``` -The only thing left to do is to call the `update` method on the `Camera` so it can smoothly follow +The only thing left to do is to call the `update` method on the `Camera` so it can smoothly follow your given position: ```dart - // ... - + @override void update(double dt) { camera?.update(dt); // Rest of your update code. } - - // ... ``` diff --git a/doc/flame/game.md b/doc/flame/game.md index 5d47891f3..e132608c7 100644 --- a/doc/flame/game.md +++ b/doc/flame/game.md @@ -41,10 +41,12 @@ main() { } ``` -**Note:** If you instantiate your game in a build method your game will be rebuilt every time the - Flutter tree gets rebuilt, which usually is more often than you'd like. To avoid this, you can - instead create an instance of your game first and reference it within your widget structure, like - it is done in the example above. +```{note} +If you instantiate your game in a build method your game will be rebuilt every time the +Flutter tree gets rebuilt, which usually is more often than you'd like. To avoid this, you can +instead create an instance of your game first and reference it within your widget structure, like +it is done in the example above. +``` To remove components from the list on a `FlameGame` the `remove` or `removeAll` methods can be used. The first can be used if you just want to remove one component, and the second can be used when you @@ -103,7 +105,7 @@ just draw a background that covers the whole canvas if you would want it to chan ## SingleGameInstance mixin An optional mixin `SingleGameInstance` can be applied to your game if you are making a single-game -application. This is a common scenario when building games: there is a single full-screen +application. This is a common scenario when building games: there is a single full-screen `GameWidget` which hosts a single `Game` instance. Adding this mixin provides performance advantages in certain scenarios. In particular, a component's @@ -123,7 +125,7 @@ class MyGame extends FlameGame with SingleGameInstance { ![Game low-level API](../images/game_mixin.png) -The `Game` mixin is a low-level API that can be used when you want to implement the functionality of +The `Game` class is a low-level API that can be used when you want to implement the functionality of how the game engine should be structured. `Game` does not implement any `update` or `render` function for example. @@ -133,13 +135,15 @@ called from the `GameWidget` (or another parent) when the game is loaded + mount called after `onLoad`) is called every time it is added to a new parent. `onRemove` is called when the class is removed from a parent. -**Note**: The `Game` mixin allows for more freedom of how to implement things, but you are also +```{note} +The `Game` class allows for more freedom of how to implement things, but you are also missing out on all of the built-in features in Flame if you use it. +``` An example of how a `Game` implementation could look like: ```dart -class MyGameSubClass with Game { +class MyGameSubClass extends Game { @override void render(Canvas canvas) { // ... @@ -151,7 +155,7 @@ class MyGameSubClass with Game { } } -main() { +void main() { final myGame = MyGameSubClass(); runApp( GameWidget( @@ -202,7 +206,7 @@ by setting a `overlayBuilderMap`. void main() { // Inside the game methods: final pauseOverlayIdentifier = 'PauseMenu'; - + // Marks 'PauseMenu' to be rendered. overlays.add(pauseOverlayIdentifier); // Marks 'PauseMenu' to not be rendered. @@ -226,8 +230,8 @@ Widget build(BuildContext context) { } ``` -The order of rendering for an overlay is determined by the order of the keys in the -`overlayBuilderMap`. +The order of rendering for an overlay is determined by the order of the keys in the +`overlayBuilderMap`. -An example of feature can be found +An example of feature can be found [here](https://github.com/flame-engine/flame/blob/main/examples/lib/stories/system/overlays_example.dart). diff --git a/examples/lib/stories/parallax/no_fcs_parallax_example.dart b/examples/lib/stories/parallax/no_fcs_parallax_example.dart index f2dd18888..c9b74434b 100644 --- a/examples/lib/stories/parallax/no_fcs_parallax_example.dart +++ b/examples/lib/stories/parallax/no_fcs_parallax_example.dart @@ -2,7 +2,7 @@ import 'package:flame/extensions.dart'; import 'package:flame/game.dart'; import 'package:flame/parallax.dart'; -class NoFCSParallaxExample with Game { +class NoFCSParallaxExample extends Game { static const String description = ''' This examples serves to test the Parallax feature outside of the Flame Component System (FCS), use the other files in this folder for examples on diff --git a/examples/lib/stories/system/without_flamegame_example.dart b/examples/lib/stories/system/without_flamegame_example.dart index a365f8b33..870baf0e6 100644 --- a/examples/lib/stories/system/without_flamegame_example.dart +++ b/examples/lib/stories/system/without_flamegame_example.dart @@ -4,7 +4,7 @@ import 'package:flame/palette.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; -class NoFlameGameExample with Game, KeyboardEvents { +class NoFlameGameExample extends Game with KeyboardEvents { static const String description = ''' This example showcases how to create a game without the FlameGame. It also briefly showcases how to act on keyboard events. diff --git a/packages/flame/lib/game.dart b/packages/flame/lib/game.dart index 44e84efc1..8542e236b 100644 --- a/packages/flame/lib/game.dart +++ b/packages/flame/lib/game.dart @@ -5,9 +5,9 @@ export 'src/extensions/vector2.dart'; export 'src/game/camera/camera.dart'; export 'src/game/camera/viewport.dart'; export 'src/game/flame_game.dart'; +export 'src/game/game.dart'; export 'src/game/game_widget/game_widget.dart'; export 'src/game/mixins/fps_counter.dart'; -export 'src/game/mixins/game.dart'; export 'src/game/mixins/has_draggables.dart'; export 'src/game/mixins/has_hoverables.dart'; export 'src/game/mixins/has_tappables.dart'; diff --git a/packages/flame/lib/src/components/component.dart b/packages/flame/lib/src/components/component.dart index 37a087499..89da6e6ab 100644 --- a/packages/flame/lib/src/components/component.dart +++ b/packages/flame/lib/src/components/component.dart @@ -7,7 +7,7 @@ import 'package:flame/src/components/component_set.dart'; import 'package:flame/src/components/mixins/coordinate_transform.dart'; import 'package:flame/src/components/position_type.dart'; import 'package:flame/src/game/flame_game.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flame/src/text/text_paint.dart'; import 'package:flutter/painting.dart'; diff --git a/packages/flame/lib/src/events/flame_drag_adapter.dart b/packages/flame/lib/src/events/flame_drag_adapter.dart index eb853053c..434d62f2e 100644 --- a/packages/flame/lib/src/events/flame_drag_adapter.dart +++ b/packages/flame/lib/src/events/flame_drag_adapter.dart @@ -1,5 +1,5 @@ import 'package:flame/src/events/interfaces/multi_drag_listener.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flutter/gestures.dart'; import 'package:meta/meta.dart'; diff --git a/packages/flame/lib/src/events/game_mixins/multi_touch_drag_detector.dart b/packages/flame/lib/src/events/game_mixins/multi_touch_drag_detector.dart index d143219d1..fd664fa46 100644 --- a/packages/flame/lib/src/events/game_mixins/multi_touch_drag_detector.dart +++ b/packages/flame/lib/src/events/game_mixins/multi_touch_drag_detector.dart @@ -1,6 +1,6 @@ import 'package:flame/src/events/flame_game_mixins/has_draggable_components.dart'; import 'package:flame/src/events/interfaces/multi_drag_listener.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flame/lib/src/events/game_mixins/multi_touch_tap_detector.dart b/packages/flame/lib/src/events/game_mixins/multi_touch_tap_detector.dart index cd310220f..3635fb920 100644 --- a/packages/flame/lib/src/events/game_mixins/multi_touch_tap_detector.dart +++ b/packages/flame/lib/src/events/game_mixins/multi_touch_tap_detector.dart @@ -1,6 +1,6 @@ import 'package:flame/src/events/flame_game_mixins/has_tappable_components.dart'; import 'package:flame/src/events/interfaces/multi_tap_listener.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flame/lib/src/events/messages/tap_down_event.dart b/packages/flame/lib/src/events/messages/tap_down_event.dart index 6052c1dbf..74f89e6b1 100644 --- a/packages/flame/lib/src/events/messages/tap_down_event.dart +++ b/packages/flame/lib/src/events/messages/tap_down_event.dart @@ -4,7 +4,7 @@ import 'package:flame/src/events/flame_game_mixins/has_tappable_components.dart' import 'package:flame/src/events/messages/position_event.dart'; import 'package:flame/src/events/messages/tap_cancel_event.dart'; import 'package:flame/src/events/messages/tap_up_event.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flame/lib/src/events/messages/tap_up_event.dart b/packages/flame/lib/src/events/messages/tap_up_event.dart index 547d7bfdf..c57a48c67 100644 --- a/packages/flame/lib/src/events/messages/tap_up_event.dart +++ b/packages/flame/lib/src/events/messages/tap_up_event.dart @@ -1,7 +1,7 @@ import 'package:flame/extensions.dart'; import 'package:flame/src/events/messages/position_event.dart'; import 'package:flame/src/events/messages/tap_down_event.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flame/lib/src/game/flame_game.dart b/packages/flame/lib/src/game/flame_game.dart index dcbdb8bfc..2d12cc767 100644 --- a/packages/flame/lib/src/game/flame_game.dart +++ b/packages/flame/lib/src/game/flame_game.dart @@ -4,7 +4,7 @@ import 'package:flame/src/components/component.dart'; import 'package:flame/src/extensions/vector2.dart'; import 'package:flame/src/game/camera/camera.dart'; import 'package:flame/src/game/camera/camera_wrapper.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/game/projector.dart'; import 'package:meta/meta.dart'; diff --git a/packages/flame/lib/src/game/mixins/game.dart b/packages/flame/lib/src/game/game.dart similarity index 98% rename from packages/flame/lib/src/game/mixins/game.dart rename to packages/flame/lib/src/game/game.dart index c075e7a88..42455aad1 100644 --- a/packages/flame/lib/src/game/mixins/game.dart +++ b/packages/flame/lib/src/game/game.dart @@ -10,11 +10,11 @@ import 'package:meta/meta.dart'; /// This gives access to a low-level game API, to not build everything from a /// low level `FlameGame` should be used. /// -/// Add this mixin to your game class and implement the [update] and [render] -/// methods to use it in a `GameWidget`. -/// Flame will deal with calling these methods properly when the game's widget -/// is rendered. -mixin Game { +/// You can either extend this class, or add it as a mixin. +/// +/// Methods [update] and [render] need to be implemented in order to connect +/// your class with the internal game loop. +abstract class Game { final images = Images(); final assets = AssetsCache(); diff --git a/packages/flame/lib/src/game/game_render_box.dart b/packages/flame/lib/src/game/game_render_box.dart index d2a96ccc9..d43af0c66 100644 --- a/packages/flame/lib/src/game/game_render_box.dart +++ b/packages/flame/lib/src/game/game_render_box.dart @@ -1,5 +1,5 @@ +import 'package:flame/src/game/game.dart'; import 'package:flame/src/game/game_loop.dart'; -import 'package:flame/src/game/mixins/game.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart' hide WidgetBuilder; //ignore_for_file: unnecessary_non_null_assertion diff --git a/packages/flame/lib/src/game/game_widget/game_widget.dart b/packages/flame/lib/src/game/game_widget/game_widget.dart index badb3f4f7..d4b65487e 100644 --- a/packages/flame/lib/src/game/game_widget/game_widget.dart +++ b/packages/flame/lib/src/game/game_widget/game_widget.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flame/extensions.dart'; import 'package:flame/input.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/game/game_render_box.dart'; import 'package:flame/src/game/game_widget/gestures.dart'; -import 'package:flame/src/game/mixins/game.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/flame/lib/src/game/game_widget/gestures.dart b/packages/flame/lib/src/game/game_widget/gestures.dart index 94ef2abf5..1226fa080 100644 --- a/packages/flame/lib/src/game/game_widget/gestures.dart +++ b/packages/flame/lib/src/game/game_widget/gestures.dart @@ -1,6 +1,6 @@ import 'package:flame/events.dart'; import 'package:flame/src/events/flame_drag_adapter.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/flame/lib/src/game/mixins/single_game_instance.dart b/packages/flame/lib/src/game/mixins/single_game_instance.dart index a4270c82b..ee9558e46 100644 --- a/packages/flame/lib/src/game/mixins/single_game_instance.dart +++ b/packages/flame/lib/src/game/mixins/single_game_instance.dart @@ -1,5 +1,5 @@ import 'package:flame/src/components/component.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; /// Mixin that declares a [Game] class as a singleton. /// diff --git a/packages/flame/lib/src/gestures/detectors.dart b/packages/flame/lib/src/gestures/detectors.dart index 427d4190e..13cb63ac6 100644 --- a/packages/flame/lib/src/gestures/detectors.dart +++ b/packages/flame/lib/src/gestures/detectors.dart @@ -1,4 +1,4 @@ -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flame/src/gestures/events.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flame/lib/src/gestures/events.dart b/packages/flame/lib/src/gestures/events.dart index 50e9b6299..9f2fcfcf8 100644 --- a/packages/flame/lib/src/gestures/events.dart +++ b/packages/flame/lib/src/gestures/events.dart @@ -1,5 +1,5 @@ import 'package:flame/extensions.dart'; -import 'package:flame/src/game/mixins/game.dart'; +import 'package:flame/src/game/game.dart'; import 'package:flutter/gestures.dart'; /// [EventPosition] converts position based events to three different coordinate diff --git a/packages/flame_oxygen/lib/src/oxygen_game.dart b/packages/flame_oxygen/lib/src/oxygen_game.dart index bb88c208b..441f9f0b1 100644 --- a/packages/flame_oxygen/lib/src/oxygen_game.dart +++ b/packages/flame_oxygen/lib/src/oxygen_game.dart @@ -10,7 +10,7 @@ import 'package:oxygen/oxygen.dart'; /// [OxygenGame] should be extended to add your own game logic. /// /// It is based on the Oxygen package. -abstract class OxygenGame with Game { +abstract class OxygenGame extends Game { late final FlameWorld world; OxygenGame() {