From 47aba31eff10a40493bfa1334fabd807ce011e24 Mon Sep 17 00:00:00 2001 From: Renan Date: Tue, 6 Oct 2020 14:13:31 +0100 Subject: [PATCH] Fix resizable conflict (#483) --- CHANGELOG.md | 2 ++ FAQ.md | 2 +- doc/examples/debug/lib/main.dart | 6 ++--- doc/examples/joystick/lib/player.dart | 4 +-- lib/components/component.dart | 10 +++---- .../joystick/joystick_component.dart | 4 +-- lib/components/mixins/resizable.dart | 25 ++++++++--------- lib/components/parallax_component.dart | 4 +-- lib/components/position_component.dart | 6 ++--- lib/components/text_box_component.dart | 2 +- lib/game/base_game.dart | 6 ++--- test/components/composed_component_test.dart | 2 +- test/components/resizable_test.dart | 27 +++++++++---------- 13 files changed, 48 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b04766d6..ecb187fd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Rebuild of Images, Sprite and SpriteAnimation initialization - Use isRelative on effects - Use Vector2 for position and size on PositionComponent + - Rename `resize` method on components to `onGameResize` + - Make `Resizable` have a `gameSize` property instead of `size` ## [next] - Fix spriteAsWidget deprecation message diff --git a/FAQ.md b/FAQ.md index a241a8813..db7139332 100644 --- a/FAQ.md +++ b/FAQ.md @@ -44,7 +44,7 @@ If you want a more full-fledged game, please check [BGUG](https://github.com/fir `Game` is the most barebones interface that Flame exposes. If you crete a Game, you will need to implement a lot of stuff. Flame will hook you up on the game loop, so you will get to implement `render` and `update` yourself. From scratch. If you wanna use the component system, you can, but you don't need to. You do everything yourself. -`BaseGame` extends `Game` and adds lots of functionality on top of that. Just drop your components, it works! They are rendered, updated, resized, automatically. You might still want to override some of `BaseGame`'s methods to add custom functionality, but you will probably be calling the super method to let `BaseGame` do its work. +`BaseGame` extends `Game` and adds lots of functionality on top of that. Just drop your components, it works! They are rendered and updated, automatically. You might still want to override some of `BaseGame`'s methods to add custom functionality, but you will probably be calling the super method to let `BaseGame` do its work. ## How does the Camera work? diff --git a/doc/examples/debug/lib/main.dart b/doc/examples/debug/lib/main.dart index 02536fdb8..8447251f2 100644 --- a/doc/examples/debug/lib/main.dart +++ b/doc/examples/debug/lib/main.dart @@ -27,7 +27,7 @@ class AndroidComponent extends SpriteComponent with Resizable { @override void update(double dt) { super.update(dt); - if (size == null) { + if (gameSize == null) { return; } @@ -36,14 +36,14 @@ class AndroidComponent extends SpriteComponent with Resizable { final rect = toRect(); if ((x <= 0 && xDirection == -1) || - (rect.right >= size.x && xDirection == 1)) { + (rect.right >= gameSize.x && xDirection == 1)) { xDirection = xDirection * -1; } y += yDirection * SPEED * dt; if ((y <= 0 && yDirection == -1) || - (rect.bottom >= size.y && yDirection == 1)) { + (rect.bottom >= gameSize.y && yDirection == 1)) { yDirection = yDirection * -1; } } diff --git a/doc/examples/joystick/lib/player.dart b/doc/examples/joystick/lib/player.dart index 886297bdf..2781dbd51 100644 --- a/doc/examples/joystick/lib/player.dart +++ b/doc/examples/joystick/lib/player.dart @@ -43,14 +43,14 @@ class Player extends Component implements JoystickListener { } @override - void resize(Vector2 size) { + void onGameResize(Vector2 size) { _rect = Rect.fromLTWH( (size.x / 2) - 25, (size.y / 2) - 25, 50, 50, ); - super.resize(size); + super.onGameResize(size); } @override diff --git a/lib/components/component.dart b/lib/components/component.dart index eb4e7f992..4319f89de 100644 --- a/lib/components/component.dart +++ b/lib/components/component.dart @@ -20,11 +20,11 @@ abstract class Component { /// Renders this component on the provided Canvas [c]. void render(Canvas c); - /// This is a hook called by [BaseGame] to let this component know that the screen (or flame draw area) has been update. + /// It receives the new game size. + /// Executed right after the component is attached to a game and right before [onMount] is called /// - /// It receives the new size. - /// You can use the [Resizable] mixin if you want an implementation of this hook that keeps track of the current size. - void resize(Vector2 size) {} + /// Use [Resizable] to save the gameSize in a component. + void onGameResize(Vector2 gameSize) {} /// Whether this component has been loaded yet. If not loaded, [BaseGame] will not try to render it. /// @@ -53,7 +53,7 @@ abstract class Component { /// Called when the component has been added and prepared by the game instance. /// /// This can be used to make initializations on your component as, when this method is called, - /// things like resize (and other mixins) are already set and usable. + /// things like [onGameResize] are already set and usable. void onMount() {} /// Called right before the component is destroyed and removed from the game diff --git a/lib/components/joystick/joystick_component.dart b/lib/components/joystick/joystick_component.dart index a0137165d..4c0d3e4dd 100644 --- a/lib/components/joystick/joystick_component.dart +++ b/lib/components/joystick/joystick_component.dart @@ -70,10 +70,10 @@ class JoystickComponent extends JoystickController { } @override - void resize(Vector2 size) { + void onGameResize(Vector2 size) { directional?.initialize(size, this); actions?.forEach((action) => action.initialize(size, this)); - super.resize(size); + super.onGameResize(size); } @override diff --git a/lib/components/mixins/resizable.dart b/lib/components/mixins/resizable.dart index f02eb39d5..581e28630 100644 --- a/lib/components/mixins/resizable.dart +++ b/lib/components/mixins/resizable.dart @@ -1,21 +1,18 @@ +import 'package:meta/meta.dart'; import '../../extensions/vector2.dart'; +import '../component.dart'; -/// Useful mixin to add to your components if you want to hold a reference to the current screen size. -/// -/// This mixin implements the resize method in order to hold an updated reference to the current screen [size]. -/// Also, it updates its [children], if any. -class Resizable { +/// A [Component] mixin to make your component keep track of the size of the game viewport. +mixin Resizable on Component { /// This is the current updated screen size. - Vector2 size; + Vector2 gameSize; /// Implementation provided by this mixin to the resize hook. - void resize(Vector2 size) { - this.size = size; - resizableChildren().forEach((e) => e?.resize(size)); + /// This is a hook called by [BaseGame] to let this component know that the screen (or flame draw area) has been update. + @override + @mustCallSuper + void onGameResize(Vector2 gameSize) { + super.onGameResize(gameSize); + this.gameSize = gameSize; } - - /// Overwrite this to add children to this [Resizable]. - /// - /// If a [Resizable] has children, its children as resized as well. - Iterable resizableChildren() => []; } diff --git a/lib/components/parallax_component.dart b/lib/components/parallax_component.dart index b6c6befac..b9d41a759 100644 --- a/lib/components/parallax_component.dart +++ b/lib/components/parallax_component.dart @@ -179,8 +179,8 @@ class ParallaxComponent extends PositionComponent { @mustCallSuper @override - void resize(Vector2 size) { - super.resize(size); + void onGameResize(Vector2 size) { + super.onGameResize(size); _layers.forEach((layer) => layer.resize(size)); } diff --git a/lib/components/position_component.dart b/lib/components/position_component.dart index 69d596ead..c58930325 100644 --- a/lib/components/position_component.dart +++ b/lib/components/position_component.dart @@ -184,9 +184,9 @@ abstract class PositionComponent extends Component { @mustCallSuper @override - void resize(Vector2 size) { - super.resize(size); - _children.forEach((child) => child.resize(size)); + void onGameResize(Vector2 gameSize) { + super.onGameResize(gameSize); + _children.forEach((child) => child.onGameResize(gameSize)); } @mustCallSuper diff --git a/lib/components/text_box_component.dart b/lib/components/text_box_component.dart index 0e00110c5..209f23e10 100644 --- a/lib/components/text_box_component.dart +++ b/lib/components/text_box_component.dart @@ -148,7 +148,7 @@ class TextBoxComponent extends PositionComponent with Resizable { Future _redrawCache() { final PictureRecorder recorder = PictureRecorder(); - final Canvas c = Canvas(recorder, size.toRect()); + final Canvas c = Canvas(recorder, gameSize.toRect()); _fullRender(c); return recorder.endRecording().toImage(width.toInt(), height.toInt()); } diff --git a/lib/game/base_game.dart b/lib/game/base_game.dart index 7ed77e615..89314ef1c 100644 --- a/lib/game/base_game.dart +++ b/lib/game/base_game.dart @@ -30,7 +30,7 @@ class BaseGame extends Game with FPSCounter { /// Components to be removed on the next update final List _removeLater = []; - /// Current screen size, updated every resize via the [resize] method hook + /// Current game viewport size, updated every resize via the [resize] method hook Vector2 size; /// Camera position; every non-HUD component is translated so that the camera position is the top-left corner of the screen. @@ -59,7 +59,7 @@ class BaseGame extends Game with FPSCounter { // first time resize if (size != null) { - c.resize(size); + c.onGameResize(size); } c.onMount(); @@ -140,7 +140,7 @@ class BaseGame extends Game with FPSCounter { @mustCallSuper void resize(Vector2 size) { this.size = size; - components.forEach((c) => c.resize(size)); + components.forEach((c) => c.onGameResize(size)); } /// Returns whether this [Game] is in debug mode or not. diff --git a/test/components/composed_component_test.dart b/test/components/composed_component_test.dart index dc9475721..767340173 100644 --- a/test/components/composed_component_test.dart +++ b/test/components/composed_component_test.dart @@ -43,7 +43,7 @@ void main() { game.add(wrapper); game.onTapDown(1, TapDownDetails(globalPosition: const Offset(0.0, 0.0))); - expect(child.size, size); + expect(child.gameSize, size); expect(child.tapped, true); }); }); diff --git a/test/components/resizable_test.dart b/test/components/resizable_test.dart index fcc7cc4bd..51e98e23a 100644 --- a/test/components/resizable_test.dart +++ b/test/components/resizable_test.dart @@ -7,12 +7,10 @@ import 'package:flame/components/mixins/resizable.dart'; class MyComponent extends PositionComponent with Resizable { String name; - List myChildren; - - MyComponent(this.name, {this.myChildren = const []}); - @override - Iterable resizableChildren() => myChildren; + Vector2 size = Vector2(2.0, 2.0); + + MyComponent(this.name); } class MyGame extends BaseGame {} @@ -21,27 +19,26 @@ Vector2 size = Vector2(1.0, 1.0); void main() { group('resizable test', () { - test('propagate resize to children', () { - final MyComponent a = MyComponent('a'); - final MyComponent b = MyComponent('b', myChildren: [a]); - b.resize(size); - expect(a.size, size); - }); - test('game calls resize on add', () { final MyComponent a = MyComponent('a'); final MyGame game = MyGame(); game.resize(size); game.add(a); - expect(a.size, size); + expect(a.gameSize, size); }); - test('game calls resize after added', () { final MyComponent a = MyComponent('a'); final MyGame game = MyGame(); game.add(a); game.resize(size); - expect(a.size, size); + expect(a.gameSize, size); + }); + test('game calls doesnt change component size', () { + final MyComponent a = MyComponent('a'); + final MyGame game = MyGame(); + game.add(a); + game.resize(size); + expect(a.size, isNot(size)); }); }); }