From 3a638157702821ef89afca8e62e1f5c97ce4fc1a Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Fri, 8 Apr 2022 17:02:46 -0700 Subject: [PATCH 1/8] Added Component.children --- packages/flame/lib/src/components/component.dart | 7 ++++++- packages/flame/lib/src/components/position_component.dart | 3 ++- packages/flame/lib/src/components/sprite_component.dart | 2 ++ .../flame/lib/src/components/sprite_group_component.dart | 2 ++ .../flame/lib/src/experimental/circular_viewport.dart | 4 +++- .../lib/src/experimental/fixed_aspect_ratio_viewport.dart | 8 ++++++-- .../flame/lib/src/experimental/fixed_size_viewport.dart | 7 ++++++- packages/flame/lib/src/experimental/max_viewport.dart | 3 +++ packages/flame/lib/src/experimental/viewport.dart | 2 ++ 9 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/flame/lib/src/components/component.dart b/packages/flame/lib/src/components/component.dart index 8f2a4716153..2bcadf98b5e 100644 --- a/packages/flame/lib/src/components/component.dart +++ b/packages/flame/lib/src/components/component.dart @@ -17,7 +17,12 @@ import '../cache/value_cache.dart'; /// called automatically once the component is added to the component tree in /// your game (with `game.add`). class Component { - Component({int? priority}) : _priority = priority ?? 0; + Component({Iterable? children, int? priority}) + : _priority = priority ?? 0 { + if (children != null) { + addAll(children); + } + } /// What coordinate system this component should respect (i.e. should it /// observe camera, viewport, or use the raw canvas). diff --git a/packages/flame/lib/src/components/position_component.dart b/packages/flame/lib/src/components/position_component.dart index a0a2a155ac3..91f744cbb4e 100644 --- a/packages/flame/lib/src/components/position_component.dart +++ b/packages/flame/lib/src/components/position_component.dart @@ -65,11 +65,12 @@ class PositionComponent extends Component implements PositionProvider { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : transform = Transform2D(), _anchor = anchor ?? Anchor.topLeft, _size = NotifyingVector2.copy(size ?? Vector2.zero()), - super(priority: priority) { + super(children: children, priority: priority) { if (position != null) { transform.position = position; } diff --git a/packages/flame/lib/src/components/sprite_component.dart b/packages/flame/lib/src/components/sprite_component.dart index adc54c73f81..b221a4946f9 100644 --- a/packages/flame/lib/src/components/sprite_component.dart +++ b/packages/flame/lib/src/components/sprite_component.dart @@ -25,6 +25,7 @@ class SpriteComponent extends PositionComponent with HasPaint { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -32,6 +33,7 @@ class SpriteComponent extends PositionComponent with HasPaint { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { if (paint != null) { diff --git a/packages/flame/lib/src/components/sprite_group_component.dart b/packages/flame/lib/src/components/sprite_group_component.dart index 21129a02e9c..a31c9391949 100644 --- a/packages/flame/lib/src/components/sprite_group_component.dart +++ b/packages/flame/lib/src/components/sprite_group_component.dart @@ -25,6 +25,7 @@ class SpriteGroupComponent extends PositionComponent with HasPaint { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -32,6 +33,7 @@ class SpriteGroupComponent extends PositionComponent with HasPaint { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { if (paint != null) { diff --git a/packages/flame/lib/src/experimental/circular_viewport.dart b/packages/flame/lib/src/experimental/circular_viewport.dart index 40fea9e3082..ff2fd44ad59 100644 --- a/packages/flame/lib/src/experimental/circular_viewport.dart +++ b/packages/flame/lib/src/experimental/circular_viewport.dart @@ -1,11 +1,13 @@ import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; +import '../components/component.dart'; import 'viewport.dart'; /// A fixed-size viewport in the shape of a circle. class CircularViewport extends Viewport { - CircularViewport(double radius) { + CircularViewport(double radius, {Iterable? children}) + : super(children: children) { size = Vector2.all(2 * radius); } diff --git a/packages/flame/lib/src/experimental/fixed_aspect_ratio_viewport.dart b/packages/flame/lib/src/experimental/fixed_aspect_ratio_viewport.dart index 6cda0521442..3fed3954155 100644 --- a/packages/flame/lib/src/experimental/fixed_aspect_ratio_viewport.dart +++ b/packages/flame/lib/src/experimental/fixed_aspect_ratio_viewport.dart @@ -2,11 +2,15 @@ import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; +import '../components/component.dart'; import 'viewport.dart'; class FixedAspectRatioViewport extends Viewport { - FixedAspectRatioViewport({required this.aspectRatio}) - : assert(aspectRatio > 0); + FixedAspectRatioViewport({ + required this.aspectRatio, + Iterable? children, + }) : assert(aspectRatio > 0), + super(children: children); final double aspectRatio; Rect _clipRect = Rect.zero; diff --git a/packages/flame/lib/src/experimental/fixed_size_viewport.dart b/packages/flame/lib/src/experimental/fixed_size_viewport.dart index 39f84daca8e..26dbbdf1904 100644 --- a/packages/flame/lib/src/experimental/fixed_size_viewport.dart +++ b/packages/flame/lib/src/experimental/fixed_size_viewport.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; +import '../components/component.dart'; import 'viewport.dart'; /// A rectangular viewport with fixed dimensions. @@ -9,7 +10,11 @@ import 'viewport.dart'; /// You can change the size of this viewport at runtime, but it will not /// auto-resize when its parent changes size. class FixedSizeViewport extends Viewport { - FixedSizeViewport(double width, double height) { + FixedSizeViewport( + double width, + double height, { + Iterable? children, + }) : super(children: children) { size = Vector2(width, height); onViewportResize(); } diff --git a/packages/flame/lib/src/experimental/max_viewport.dart b/packages/flame/lib/src/experimental/max_viewport.dart index 8ecbe776534..70357306081 100644 --- a/packages/flame/lib/src/experimental/max_viewport.dart +++ b/packages/flame/lib/src/experimental/max_viewport.dart @@ -2,12 +2,15 @@ import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; +import '../components/component.dart'; import 'viewport.dart'; /// The default viewport, which is as big as the game canvas allows. /// /// This viewport does not perform any clipping. class MaxViewport extends Viewport { + MaxViewport({Iterable? children}) : super(children: children); + @override void onGameResize(Vector2 gameSize) { super.onGameResize(gameSize); diff --git a/packages/flame/lib/src/experimental/viewport.dart b/packages/flame/lib/src/experimental/viewport.dart index 891a8dfcc97..45c35eca017 100644 --- a/packages/flame/lib/src/experimental/viewport.dart +++ b/packages/flame/lib/src/experimental/viewport.dart @@ -18,6 +18,8 @@ import 'camera_component.dart'; /// shape, and also by their behavior in response to changes to the canvas size. /// Users may also create their own implementations. abstract class Viewport extends Component implements PositionProvider { + Viewport({Iterable? children}) : super(children: children); + /// Position of the viewport's center in the parent's coordinate frame. /// /// Changing this position will move the viewport around the screen, but will From 514eeacf3b0e03fd6f17c30753f247b6a1488597 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Fri, 8 Apr 2022 17:11:24 -0700 Subject: [PATCH 2/8] Added tests --- .../flame/test/components/component_test.dart | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/flame/test/components/component_test.dart b/packages/flame/test/components/component_test.dart index 7f611cacf2d..891ca7cae9f 100644 --- a/packages/flame/test/components/component_test.dart +++ b/packages/flame/test/components/component_test.dart @@ -45,6 +45,36 @@ void main() { final prepareGame = FlameTester(() => _PrepareGame()); group('Component', () { + testWithFlameGame('children in the constructor', (game) async { + game.add( + Component( + children: [ComponentA(), ComponentB()], + ), + ); + await game.ready(); + + expect(game.children.length, 1); + expect(game.children.first.children.length, 2); + expect(game.children.first.children.elementAt(0), isA()); + expect(game.children.first.children.elementAt(1), isA()); + }); + + testWithFlameGame('children in constructor and onLoad', (game) async { + final component = TwoChildrenComponent( + children: [ComponentA(), ComponentB()], + ); + game.add(component); + await game.ready(); + + expect(game.children.length, 1); + expect(game.children.first, component); + expect(component.children.length, 4); + expect(component.children.elementAt(0), isA()); + expect(component.children.elementAt(1), isA()); + expect(component.children.elementAt(2), component.child1); + expect(component.children.elementAt(3), component.child2); + }); + test('get/set x/y or position', () { final PositionComponent c = SpriteComponent(); c.position.setValues(2.2, 3.4); @@ -426,3 +456,19 @@ class Visitor extends Component { class IntComponent extends Component { int value = 0; } + +class TwoChildrenComponent extends Component { + TwoChildrenComponent({Iterable? children}) + : super(children: children); + + late final Component child1; + late final Component child2; + + @override + Future onLoad() async { + child1 = Component(); + child2 = Component(); + add(child1); + add(child2); + } +} From c77534c1be4568da309b16887d11f11e514f47b0 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 00:55:17 -0700 Subject: [PATCH 3/8] Added children parameter to all components --- .../flame/lib/src/components/custom_painter_component.dart | 2 ++ .../flame/lib/src/components/input/button_component.dart | 2 ++ .../lib/src/components/input/hud_button_component.dart | 2 ++ .../lib/src/components/input/hud_margin_component.dart | 2 ++ .../flame/lib/src/components/input/joystick_component.dart | 2 ++ .../lib/src/components/input/sprite_button_component.dart | 2 ++ .../lib/src/components/isometric_tile_map_component.dart | 2 ++ .../flame/lib/src/components/nine_tile_box_component.dart | 2 ++ packages/flame/lib/src/components/parallax_component.dart | 2 ++ .../flame/lib/src/components/particle_system_component.dart | 2 ++ .../lib/src/components/sprite_animation_component.dart | 2 ++ .../src/components/sprite_animation_group_component.dart | 2 ++ .../flame/lib/src/components/sprite_batch_component.dart | 3 ++- packages/flame/lib/src/components/text_box_component.dart | 2 ++ packages/flame/lib/src/components/text_component.dart | 2 ++ packages/flame/lib/src/geometry/circle_component.dart | 2 ++ packages/flame/lib/src/geometry/polygon_component.dart | 2 ++ packages/flame/lib/src/geometry/rectangle_component.dart | 2 ++ packages/flame/lib/src/geometry/shape_component.dart | 2 ++ packages/flame_forge2d/lib/body_component.dart | 6 +++++- packages/flame_rive/lib/src/rive_component.dart | 2 ++ packages/flame_svg/lib/svg_component.dart | 2 ++ packages/flame_tiled/lib/src/tiled_component.dart | 6 +++++- 23 files changed, 52 insertions(+), 3 deletions(-) diff --git a/packages/flame/lib/src/components/custom_painter_component.dart b/packages/flame/lib/src/components/custom_painter_component.dart index 8543bb85a59..e692d5deb5a 100644 --- a/packages/flame/lib/src/components/custom_painter_component.dart +++ b/packages/flame/lib/src/components/custom_painter_component.dart @@ -22,6 +22,7 @@ class CustomPainterComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -29,6 +30,7 @@ class CustomPainterComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/input/button_component.dart b/packages/flame/lib/src/components/input/button_component.dart index 6bb3d47025e..87bc841640c 100644 --- a/packages/flame/lib/src/components/input/button_component.dart +++ b/packages/flame/lib/src/components/input/button_component.dart @@ -26,6 +26,7 @@ class ButtonComponent extends PositionComponent with Tappable { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -33,6 +34,7 @@ class ButtonComponent extends PositionComponent with Tappable { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/input/hud_button_component.dart b/packages/flame/lib/src/components/input/hud_button_component.dart index 8ec3be1455a..b4df717e467 100644 --- a/packages/flame/lib/src/components/input/hud_button_component.dart +++ b/packages/flame/lib/src/components/input/hud_button_component.dart @@ -34,6 +34,7 @@ class HudButtonComponent extends HudMarginComponent with Tappable { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( margin: margin, @@ -42,6 +43,7 @@ class HudButtonComponent extends HudMarginComponent with Tappable { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/input/hud_margin_component.dart b/packages/flame/lib/src/components/input/hud_margin_component.dart index 41675d409ac..688dcc330b2 100644 --- a/packages/flame/lib/src/components/input/hud_margin_component.dart +++ b/packages/flame/lib/src/components/input/hud_margin_component.dart @@ -30,6 +30,7 @@ class HudMarginComponent extends PositionComponent Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : assert( margin != null || position != null, @@ -41,6 +42,7 @@ class HudMarginComponent extends PositionComponent scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/input/joystick_component.dart b/packages/flame/lib/src/components/input/joystick_component.dart index 63bf706a385..bfd03a7b831 100644 --- a/packages/flame/lib/src/components/input/joystick_component.dart +++ b/packages/flame/lib/src/components/input/joystick_component.dart @@ -53,6 +53,7 @@ class JoystickComponent extends HudMarginComponent with Draggable { double? size, double? knobRadius, Anchor anchor = Anchor.center, + Iterable? children, int? priority, }) : assert( size != null || background != null, @@ -68,6 +69,7 @@ class JoystickComponent extends HudMarginComponent with Draggable { position: position, size: background?.size ?? Vector2.all(size ?? 0), anchor: anchor, + children: children, priority: priority, ) { this.knobRadius = knobRadius ?? this.size.x / 2; diff --git a/packages/flame/lib/src/components/input/sprite_button_component.dart b/packages/flame/lib/src/components/input/sprite_button_component.dart index 2a201e9f627..5abf82ff79f 100644 --- a/packages/flame/lib/src/components/input/sprite_button_component.dart +++ b/packages/flame/lib/src/components/input/sprite_button_component.dart @@ -27,6 +27,7 @@ class SpriteButtonComponent extends SpriteGroupComponent<_ButtonState> Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( current: _ButtonState.up, @@ -35,6 +36,7 @@ class SpriteButtonComponent extends SpriteGroupComponent<_ButtonState> scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/isometric_tile_map_component.dart b/packages/flame/lib/src/components/isometric_tile_map_component.dart index e2f4d34df65..490e4776e13 100644 --- a/packages/flame/lib/src/components/isometric_tile_map_component.dart +++ b/packages/flame/lib/src/components/isometric_tile_map_component.dart @@ -62,6 +62,7 @@ class IsometricTileMapComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -69,6 +70,7 @@ class IsometricTileMapComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/nine_tile_box_component.dart b/packages/flame/lib/src/components/nine_tile_box_component.dart index cb1414aff65..10ed550848b 100644 --- a/packages/flame/lib/src/components/nine_tile_box_component.dart +++ b/packages/flame/lib/src/components/nine_tile_box_component.dart @@ -22,6 +22,7 @@ class NineTileBoxComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -29,6 +30,7 @@ class NineTileBoxComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/parallax_component.dart b/packages/flame/lib/src/components/parallax_component.dart index cd46f733f5d..20531712cbb 100644 --- a/packages/flame/lib/src/components/parallax_component.dart +++ b/packages/flame/lib/src/components/parallax_component.dart @@ -66,6 +66,7 @@ class ParallaxComponent extends PositionComponent Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : _parallax = parallax, isFullscreen = size == null && !(parallax?.isSized ?? false), @@ -75,6 +76,7 @@ class ParallaxComponent extends PositionComponent scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/particle_system_component.dart b/packages/flame/lib/src/components/particle_system_component.dart index 1280685c02b..ea47eb14a7d 100644 --- a/packages/flame/lib/src/components/particle_system_component.dart +++ b/packages/flame/lib/src/components/particle_system_component.dart @@ -19,6 +19,7 @@ class ParticleSystemComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : super( position: position, @@ -26,6 +27,7 @@ class ParticleSystemComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/sprite_animation_component.dart b/packages/flame/lib/src/components/sprite_animation_component.dart index 9bc158e6dbf..28af527f293 100644 --- a/packages/flame/lib/src/components/sprite_animation_component.dart +++ b/packages/flame/lib/src/components/sprite_animation_component.dart @@ -29,6 +29,7 @@ class SpriteAnimationComponent extends PositionComponent with HasPaint { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : removeOnFinish = removeOnFinish ?? false, playing = playing ?? true, @@ -38,6 +39,7 @@ class SpriteAnimationComponent extends PositionComponent with HasPaint { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { if (paint != null) { diff --git a/packages/flame/lib/src/components/sprite_animation_group_component.dart b/packages/flame/lib/src/components/sprite_animation_group_component.dart index 0869ae0344a..3eaa02c681a 100644 --- a/packages/flame/lib/src/components/sprite_animation_group_component.dart +++ b/packages/flame/lib/src/components/sprite_animation_group_component.dart @@ -27,6 +27,7 @@ class SpriteAnimationGroupComponent extends PositionComponent with HasPaint { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : removeOnFinish = removeOnFinish ?? const {}, super( @@ -35,6 +36,7 @@ class SpriteAnimationGroupComponent extends PositionComponent with HasPaint { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { if (paint != null) { diff --git a/packages/flame/lib/src/components/sprite_batch_component.dart b/packages/flame/lib/src/components/sprite_batch_component.dart index 211021d95b9..f2edf8f2bd8 100644 --- a/packages/flame/lib/src/components/sprite_batch_component.dart +++ b/packages/flame/lib/src/components/sprite_batch_component.dart @@ -17,7 +17,8 @@ class SpriteBatchComponent extends Component { this.blendMode, this.cullRect, this.paint, - }); + Iterable? children, + }) : super(children: children); @override @mustCallSuper diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index d6d7e1047f4..03553415553 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -69,6 +69,7 @@ class TextBoxComponent extends TextComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : _boxConfig = boxConfig ?? TextBoxConfig(), pixelRatio = pixelRatio ?? window.devicePixelRatio, @@ -79,6 +80,7 @@ class TextBoxComponent extends TextComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/text_component.dart b/packages/flame/lib/src/components/text_component.dart index 1666d81fa15..b0b0b549159 100644 --- a/packages/flame/lib/src/components/text_component.dart +++ b/packages/flame/lib/src/components/text_component.dart @@ -33,6 +33,7 @@ class TextComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : _text = text ?? '', _textRenderer = textRenderer ?? TextRenderer.createDefault(), @@ -42,6 +43,7 @@ class TextComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { updateBounds(); diff --git a/packages/flame/lib/src/geometry/circle_component.dart b/packages/flame/lib/src/geometry/circle_component.dart index 160ed88eb45..d1be16a25c4 100644 --- a/packages/flame/lib/src/geometry/circle_component.dart +++ b/packages/flame/lib/src/geometry/circle_component.dart @@ -14,6 +14,7 @@ class CircleComponent extends ShapeComponent { Vector2? position, double? angle, Anchor? anchor, + Iterable? children, int? priority, Paint? paint, }) : super( @@ -21,6 +22,7 @@ class CircleComponent extends ShapeComponent { size: Vector2.all((radius ?? 0) * 2), angle: angle, anchor: anchor, + children: children, priority: priority, paint: paint, ); diff --git a/packages/flame/lib/src/geometry/polygon_component.dart b/packages/flame/lib/src/geometry/polygon_component.dart index 70d0b6dbc57..2741cc99569 100644 --- a/packages/flame/lib/src/geometry/polygon_component.dart +++ b/packages/flame/lib/src/geometry/polygon_component.dart @@ -35,6 +35,7 @@ class PolygonComponent extends ShapeComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, Paint? paint, bool? shrinkToBounds, @@ -50,6 +51,7 @@ class PolygonComponent extends ShapeComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, paint: paint, ) { diff --git a/packages/flame/lib/src/geometry/rectangle_component.dart b/packages/flame/lib/src/geometry/rectangle_component.dart index 93bfa7e8569..61820688d32 100644 --- a/packages/flame/lib/src/geometry/rectangle_component.dart +++ b/packages/flame/lib/src/geometry/rectangle_component.dart @@ -11,6 +11,7 @@ class RectangleComponent extends PolygonComponent { Vector2? size, double? angle, Anchor? anchor, + Iterable? children, int? priority, Paint? paint, }) : super( @@ -19,6 +20,7 @@ class RectangleComponent extends PolygonComponent { size: size, angle: angle, anchor: anchor, + children: children, priority: priority, paint: paint, ); diff --git a/packages/flame/lib/src/geometry/shape_component.dart b/packages/flame/lib/src/geometry/shape_component.dart index 4f61f34226a..28cf1c5126e 100644 --- a/packages/flame/lib/src/geometry/shape_component.dart +++ b/packages/flame/lib/src/geometry/shape_component.dart @@ -15,6 +15,7 @@ abstract class ShapeComponent extends PositionComponent with HasPaint { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, Paint? paint, }) : super( @@ -23,6 +24,7 @@ abstract class ShapeComponent extends PositionComponent with HasPaint { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ) { this.paint = paint ?? this.paint; diff --git a/packages/flame_forge2d/lib/body_component.dart b/packages/flame_forge2d/lib/body_component.dart index 6382fc9cf1b..234d00a3c76 100644 --- a/packages/flame_forge2d/lib/body_component.dart +++ b/packages/flame_forge2d/lib/body_component.dart @@ -22,7 +22,11 @@ abstract class BodyComponent extends Component /// it to false. bool renderBody = true; - BodyComponent({Paint? paint, int? priority}) : super(priority: priority) { + BodyComponent({ + Paint? paint, + Iterable? children, + int? priority, + }) : super(children: children, priority: priority) { this.paint = paint ?? (Paint()..color = defaultColor); } diff --git a/packages/flame_rive/lib/src/rive_component.dart b/packages/flame_rive/lib/src/rive_component.dart index b264e015a58..2dcadb16b2f 100644 --- a/packages/flame_rive/lib/src/rive_component.dart +++ b/packages/flame_rive/lib/src/rive_component.dart @@ -27,6 +27,7 @@ class RiveComponent extends PositionComponent { Vector2? scale, double angle = 0.0, Anchor anchor = Anchor.topLeft, + Iterable? children, int? priority, }) : _renderer = RiveArtboardRenderer( antialiasing: antialiasing, @@ -41,6 +42,7 @@ class RiveComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame_svg/lib/svg_component.dart b/packages/flame_svg/lib/svg_component.dart index 59fe89642da..006e8215bc2 100644 --- a/packages/flame_svg/lib/svg_component.dart +++ b/packages/flame_svg/lib/svg_component.dart @@ -17,6 +17,7 @@ class SvgComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : _svg = svg, super( @@ -25,6 +26,7 @@ class SvgComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); diff --git a/packages/flame_tiled/lib/src/tiled_component.dart b/packages/flame_tiled/lib/src/tiled_component.dart index a78a12a2ea3..1b6ff8dc2cf 100644 --- a/packages/flame_tiled/lib/src/tiled_component.dart +++ b/packages/flame_tiled/lib/src/tiled_component.dart @@ -15,7 +15,11 @@ class TiledComponent extends Component { RenderableTiledMap tileMap; /// {@macro _tiled_component} - TiledComponent(this.tileMap, {int? priority}) : super(priority: priority); + TiledComponent( + this.tileMap, { + Iterable? children, + int? priority, + }) : super(children: children, priority: priority); @override void render(Canvas canvas) { From 1fb0732f8653240a14abd74d08f108f1ef974ff8 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 01:08:13 -0700 Subject: [PATCH 4/8] Add docs --- doc/flame/components.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/doc/flame/components.md b/doc/flame/components.md index 76f25d1edb4..93d90094c60 100644 --- a/doc/flame/components.md +++ b/doc/flame/components.md @@ -93,6 +93,7 @@ the component we change the priority to 2. Sometimes it is useful to wrap other components inside of your component. For example by grouping visual components through a hierarchy. You can do this by adding child components to any component, for example `PositionComponent`. + When you have child components on a component every time the parent is updated and rendered, all the children are rendered and updated with the same conditions. @@ -122,6 +123,36 @@ class GameOverPanel extends PositionComponent with HasGameRef { } ``` +There are two methods for adding children components to your component. First, +you have methods `add()`, `addAll()`, and `addToParent()`, which can be used +at any time during the game. Traditionally, children will be created and added +from the component's `onLoad()` method, but it is also common to add new +children during the course of the game. + +The second method is to use the `children:` parameter in the component's +constructor. This approach more closely resembles the standard Flutter API: +```dart +class MyGame extends FlameGame { + @override + Future onLoad() async { + add( + PositionComponent( + position: Vector2(30, 0), + children: [ + HighScoreDisplay(), + HitPointsDisplay(), + FpsCounter(), + ], + ), + ); + } +} +``` + +The two approaches can be combined freely: the children specified within the +constructor will be added first, and then any additional child components +after. + ### Querying child components @@ -516,7 +547,7 @@ parallax), you can do it in a few different ways depending on how fine-grained y settings for each layer. They simplest way is to set the named optional parameters `baseVelocity` and -`velocityMultiplierDelta` in the `load` helper function. For example if you want to move your +`velocityMultiplierDelta` in the `load` helper function. For example if you want to move your background images along the X-axis with a faster speed the "closer" the image is: ```dart From 25f31a18c8fd493e288e027b15c9b8272c81e685 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 14:45:54 -0700 Subject: [PATCH 5/8] Added constructor to CompositeHitbox --- .../collisions/hitboxes/composite_hitbox.dart | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/flame/lib/src/collisions/hitboxes/composite_hitbox.dart b/packages/flame/lib/src/collisions/hitboxes/composite_hitbox.dart index bc41fdc47bc..fe3b853bc07 100644 --- a/packages/flame/lib/src/collisions/hitboxes/composite_hitbox.dart +++ b/packages/flame/lib/src/collisions/hitboxes/composite_hitbox.dart @@ -9,4 +9,22 @@ import '../../../components.dart'; /// those hitboxes to an instance of this class and react to collisions to the /// whole hat, instead of for just each hitbox separately. class CompositeHitbox extends PositionComponent - with CollisionCallbacks, CollisionPassthrough {} + with CollisionCallbacks, CollisionPassthrough { + CompositeHitbox({ + Vector2? position, + Vector2? size, + Vector2? scale, + double? angle, + Anchor? anchor, + Iterable? children, + int? priority, + }) : super( + position: position, + size: size, + scale: scale, + angle: angle, + anchor: anchor, + children: children, + priority: priority, + ); +} From 7de7905d0daa28192255ad825e1158b2e5d2b8c1 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 9 Apr 2022 18:07:40 -0700 Subject: [PATCH 6/8] added comment about children availability --- doc/flame/components.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/flame/components.md b/doc/flame/components.md index 93d90094c60..c829103190e 100644 --- a/doc/flame/components.md +++ b/doc/flame/components.md @@ -153,6 +153,11 @@ The two approaches can be combined freely: the children specified within the constructor will be added first, and then any additional child components after. +Note that the children added via either methods are only guaranteed to be +available eventually: after they are loaded and mounted. We can only assure +that they will appear in the children list in the same order as they were +scheduled for addition. + ### Querying child components From 77547e44de67fdac892afad7051d83d735ee2f53 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 10 Apr 2022 12:31:57 -0700 Subject: [PATCH 7/8] Removed children from SpriteBatchComponent and ParticleSystemComponent --- .../flame/lib/src/components/particle_system_component.dart | 2 -- packages/flame/lib/src/components/sprite_batch_component.dart | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/flame/lib/src/components/particle_system_component.dart b/packages/flame/lib/src/components/particle_system_component.dart index ea47eb14a7d..1280685c02b 100644 --- a/packages/flame/lib/src/components/particle_system_component.dart +++ b/packages/flame/lib/src/components/particle_system_component.dart @@ -19,7 +19,6 @@ class ParticleSystemComponent extends PositionComponent { Vector2? scale, double? angle, Anchor? anchor, - Iterable? children, int? priority, }) : super( position: position, @@ -27,7 +26,6 @@ class ParticleSystemComponent extends PositionComponent { scale: scale, angle: angle, anchor: anchor, - children: children, priority: priority, ); diff --git a/packages/flame/lib/src/components/sprite_batch_component.dart b/packages/flame/lib/src/components/sprite_batch_component.dart index f2edf8f2bd8..211021d95b9 100644 --- a/packages/flame/lib/src/components/sprite_batch_component.dart +++ b/packages/flame/lib/src/components/sprite_batch_component.dart @@ -17,8 +17,7 @@ class SpriteBatchComponent extends Component { this.blendMode, this.cullRect, this.paint, - Iterable? children, - }) : super(children: children); + }); @override @mustCallSuper From 0cd9cda965f48f33fb4ad059b264a49b5e24fb81 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Sun, 10 Apr 2022 19:05:33 +0200 Subject: [PATCH 8/8] fix: Invalidate polygon cache on resize (#1529) --- .../lib/src/geometry/polygon_component.dart | 3 +- .../collisions/collision_callback_test.dart | 65 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/packages/flame/lib/src/geometry/polygon_component.dart b/packages/flame/lib/src/geometry/polygon_component.dart index 2741cc99569..72bdef53a8a 100644 --- a/packages/flame/lib/src/geometry/polygon_component.dart +++ b/packages/flame/lib/src/geometry/polygon_component.dart @@ -159,6 +159,7 @@ class PolygonComponent extends ShapeComponent { final position = absoluteTopLeftPosition; if (!_cachedGlobalVertices.isCacheValid([ position, + size, scale, angle, ])) { @@ -178,7 +179,7 @@ class PolygonComponent extends ShapeComponent { } _cachedGlobalVertices.updateCache( _globalVertices, - [position.clone(), scale.clone(), angle], + [position.clone(), size.clone(), scale.clone(), angle], ); } return _cachedGlobalVertices.value!; diff --git a/packages/flame/test/collisions/collision_callback_test.dart b/packages/flame/test/collisions/collision_callback_test.dart index 60c9d8afe28..07dfca4c5cb 100644 --- a/packages/flame/test/collisions/collision_callback_test.dart +++ b/packages/flame/test/collisions/collision_callback_test.dart @@ -315,12 +315,7 @@ void main() { }, ); - // Reproduces #1478, it creates many blocks lined up on the diagonal with one - // empty space (one block-unit) between them. Then it moves another block so - // that it starts colliding with one of the blocks, but for some reason the - // collision is deemed to end in the same tick as it starts, which shouldn't - // be possible. If you change the amount of blocks that are generated, this - // will happen on different blocks (even though the blocks haven't moved). + // Reproduced #1478 withCollidables.test( 'collision callbacks with many hitboxes added', (game) async { @@ -343,31 +338,6 @@ void main() { } await game.ensureAddAll(blocks); - // All - // amount = 33 - 2 bad - // 10: [200.0,210.0] - // 21: [420.0,430.0] - - // amount = 100 - 6 bad - // 10: [200.0,210.0] - // 21: [420.0,430.0] - // 33: [660.0,670.0] - // 66: [1320.0,1330.0] - // 77: [1540.0,1550.0] - // 88: [1760.0,1770.0] - - // amount = 1000 - 80 bad - // 11: [220.0,230.0] - // 24: [480.0,490.0] - // 36: [720.0,730.0] - // 49: [980.0,990.0] - // 60: [1200.0,1210.0] - // ... - // 949: [18980.0,18990.0] - // 962: [19240.0,19250.0] - // 974: [19480.0,19490.0] - // 987: [19740.0,19750.0] - for (var i = 0; i < blocks.length; i++) { player.position = Vector2.all(-10000); game.update(0); @@ -407,4 +377,37 @@ void main() { expect(player.endCounter, 0); }, ); + + // Reproduced #1478 + withCollidables.test( + 'collision callbacks with changed game size', + (game) async { + final block = TestBlock(Vector2.all(20), Vector2.all(10)) + ..anchor = Anchor.center; + await game.ensureAddAll([ScreenHitbox(), block]); + + game.update(0); + expect(block.startCounter, 0); + expect(block.onCollisionCounter, 0); + expect(block.endCounter, 0); + block.position.x = game.size.x; + + game.update(0); + expect(block.startCounter, 1); + expect(block.onCollisionCounter, 1); + expect(block.endCounter, 0); + game.onGameResize(game.size * 2); + + game.update(0); + expect(block.startCounter, 1); + expect(block.onCollisionCounter, 1); + expect(block.endCounter, 1); + block.position.y = game.size.y; + + game.update(0); + expect(block.startCounter, 2); + expect(block.onCollisionCounter, 2); + expect(block.endCounter, 1); + }, + ); }