Introduce updateTree (#1158)

* Introduce updateTree

* Update tests

* Fix update for game-in-game situations

* Add dartdoc to updateTree
This commit is contained in:
Lukas Klingsbo
2021-12-03 14:01:46 +01:00
committed by GitHub
parent bc31e11d29
commit fe162c6d90
29 changed files with 43 additions and 49 deletions

View File

@ -72,7 +72,6 @@ class MovableEmber extends Ember<FollowComponentExample>
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
final deltaPosition = velocity * (speed * dt); final deltaPosition = velocity * (speed * dt);
position.add(deltaPosition); position.add(deltaPosition);
positionText.text = '(${x.toInt()}, ${y.toInt()})'; positionText.text = '(${x.toInt()}, ${y.toInt()})';

View File

@ -52,7 +52,6 @@ class MyCollidable extends PositionComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (_isWallHit) { if (_isWallHit) {
removeFromParent(); removeFromParent();
return; return;

View File

@ -89,7 +89,6 @@ class AnimatedComponent extends SpriteAnimationComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
position += velocity * dt; position += velocity * dt;
} }

View File

@ -121,7 +121,6 @@ abstract class MyCollidable extends PositionComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (_isDragged) { if (_isDragged) {
return; return;
} }

View File

@ -1,6 +1,9 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:flame/palette.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// This class only has `HasDraggables` since the game-in-game example moves a // This class only has `HasDraggables` since the game-in-game example moves a
// draggable component to this game. // draggable component to this game.
@ -32,8 +35,15 @@ class ComposabilityExample extends FlameGame with HasDraggables {
} }
class ParentSquare extends RectangleComponent with HasGameRef { class ParentSquare extends RectangleComponent with HasGameRef {
static final defaultPaint = BasicPalette.white.paint()
..style = PaintingStyle.stroke;
ParentSquare(Vector2 position, Vector2 size) ParentSquare(Vector2 position, Vector2 size)
: super(position: position, size: size); : super(
position: position,
size: size,
paint: defaultPaint,
);
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
@ -49,21 +59,25 @@ class ParentSquare extends RectangleComponent with HasGameRef {
position: Vector2(100, 100), position: Vector2(100, 100),
size: childSize, size: childSize,
angle: 2, angle: 2,
paint: defaultPaint,
), ),
RectangleComponent.square( RectangleComponent.square(
position: Vector2(160, 100), position: Vector2(160, 100),
size: childSize, size: childSize,
angle: 3, angle: 3,
paint: defaultPaint,
), ),
RectangleComponent.square( RectangleComponent.square(
position: Vector2(170, 150), position: Vector2(170, 150),
size: childSize, size: childSize,
angle: 4, angle: 4,
paint: defaultPaint,
), ),
RectangleComponent.square( RectangleComponent.square(
position: Vector2(70, 200), position: Vector2(70, 200),
size: childSize, size: childSize,
angle: 5, angle: 5,
paint: defaultPaint,
), ),
]; ];

View File

@ -61,8 +61,6 @@ class LogoComponent extends SpriteComponent with HasGameRef<DebugExample> {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
x += xDirection * speed * dt; x += xDirection * speed * dt;
final rect = toRect(); final rect = toRect();

View File

@ -23,7 +23,6 @@ class JoystickPlayer extends SpriteComponent with HasGameRef {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (!joystick.delta.isZero()) { if (!joystick.delta.isZero()) {
position.add(joystick.relativeDelta * maxSpeed * dt); position.add(joystick.relativeDelta * maxSpeed * dt);
angle = joystick.delta.screenAngle(); angle = joystick.delta.screenAngle();

View File

@ -570,7 +570,6 @@ class TrafficLightComponent extends Component {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
colorChangeTimer.update(dt); colorChangeTimer.update(dt);
} }

View File

@ -3,6 +3,7 @@
## [Next] ## [Next]
- Add `ButtonComponent` backed by two `PositionComponent`s - Add `ButtonComponent` backed by two `PositionComponent`s
- Add `SpriteButtonComponent` backed by two `Sprite`s - Add `SpriteButtonComponent` backed by two `Sprite`s
- Introduce `updateTree` to follow the `renderTree` convention
- Fix `Parallax.load` with different loading times - Fix `Parallax.load` with different loading times
## [1.0.0-releasecandidate.18] ## [1.0.0-releasecandidate.18]

View File

@ -122,10 +122,19 @@ class Component with Loadable {
/// your state considering this. /// your state considering this.
/// All components in the tree are always updated by the same amount. The time /// All components in the tree are always updated by the same amount. The time
/// each one takes to update adds up to the next update cycle. /// each one takes to update adds up to the next update cycle.
@mustCallSuper void update(double dt) {}
void update(double dt) {
/// This method traverses the component tree and calls [update] on all its
/// children according to their [priority] order, relative to the
/// priority of the direct siblings, not the children or the ancestors.
/// If you call this method from [update] you need to set [callOwnUpdate] to
/// false so that you don't get stuck in an infinite loop.
void updateTree(double dt, {bool callOwnUpdate = true}) {
children.updateComponentList(); children.updateComponentList();
children.forEach((c) => c.update(dt)); if (callOwnUpdate) {
update(dt);
}
children.forEach((c) => c.updateTree(dt));
} }
void render(Canvas canvas) {} void render(Canvas canvas) {}

View File

@ -91,7 +91,6 @@ class JoystickComponent extends HudMarginComponent with Draggable {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
final knobRadius2 = knobRadius * knobRadius; final knobRadius2 = knobRadius * knobRadius;
delta.setFrom(_unscaledDelta); delta.setFrom(_unscaledDelta);
if (delta.isZero() && _baseKnobPosition != knob!.position) { if (delta.isZero() && _baseKnobPosition != knob!.position) {

View File

@ -100,7 +100,6 @@ class ParallaxComponent<T extends FlameGame> extends PositionComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
parallax?.update(dt); parallax?.update(dt);
} }

View File

@ -31,7 +31,6 @@ class ParticleComponent extends Component {
/// Passes update chain to child [Particle]. /// Passes update chain to child [Particle].
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
particle.update(dt); particle.update(dt);
} }
} }

View File

@ -100,7 +100,6 @@ class SpriteAnimationComponent extends PositionComponent with HasPaint {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (playing) { if (playing) {
animation?.update(dt); animation?.update(dt);
} }

View File

@ -111,7 +111,6 @@ class SpriteAnimationGroupComponent<T> extends PositionComponent with HasPaint {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
animation?.update(dt); animation?.update(dt);
} }
} }

View File

@ -232,7 +232,6 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
_lifeTime += dt; _lifeTime += dt;
if (_previousChar != currentChar) { if (_previousChar != currentChar) {
redraw(); redraw();

View File

@ -39,7 +39,6 @@ class TimerComponent extends Component {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
timer.update(dt); timer.update(dt);
if (removeOnFinish && timer.finished) { if (removeOnFinish && timer.finished) {

View File

@ -64,10 +64,7 @@ class FlameGame extends Component with Game {
/// interfering with each others rendering. /// interfering with each others rendering.
@override @override
@mustCallSuper @mustCallSuper
void render(Canvas canvas) { void render(Canvas canvas) => _cameraWrapper.render(canvas);
super.render(canvas);
_cameraWrapper.render(canvas);
}
/// This updates every component in the tree. /// This updates every component in the tree.
/// ///
@ -78,7 +75,9 @@ class FlameGame extends Component with Game {
@override @override
@mustCallSuper @mustCallSuper
void update(double dt) { void update(double dt) {
super.update(dt); if (parent == null) {
super.updateTree(dt, callOwnUpdate: false);
}
_cameraWrapper.update(dt); _cameraWrapper.update(dt);
} }

View File

@ -18,13 +18,11 @@ class _MyTap extends PositionComponent with Tappable {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
updated = true; updated = true;
} }
@override @override
void render(Canvas canvas) { void render(Canvas canvas) {
super.render(canvas);
rendered = true; rendered = true;
} }
@ -78,12 +76,12 @@ void main() {
await wrapper.add(child); await wrapper.add(child);
expect(wrapper.contains(child), false); expect(wrapper.contains(child), false);
wrapper.update(0); // children are only added on the next tick wrapper.updateTree(0); // children are only added on the next tick
expect(wrapper.contains(child), true); expect(wrapper.contains(child), true);
wrapper.remove(child); wrapper.remove(child);
expect(wrapper.contains(child), true); expect(wrapper.contains(child), true);
wrapper.update(0); // children are only removed on the next tick wrapper.updateTree(0); // children are only removed on the next tick
expect(wrapper.contains(child), false); expect(wrapper.contains(child), false);
}); });
@ -98,7 +96,7 @@ void main() {
expect(wrapper.contains(child), false); expect(wrapper.contains(child), false);
await future; await future;
expect(wrapper.contains(child), false); expect(wrapper.contains(child), false);
wrapper.update(0); wrapper.updateTree(0);
expect(wrapper.contains(child), true); expect(wrapper.contains(child), true);
}, },
); );

View File

@ -30,7 +30,6 @@ class _MyComponent extends PositionComponent with HasGameRef {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
isUpdateCalled = true; isUpdateCalled = true;
} }
@ -159,9 +158,11 @@ void main() {
flameGame.test('removes PositionComponent when shouldRemove is true', flameGame.test('removes PositionComponent when shouldRemove is true',
(game) async { (game) async {
await game.ensureAdd(PositionComponent()..shouldRemove = true); final component = PositionComponent();
await game.ensureAdd(component);
expect(game.children.length, equals(1)); expect(game.children.length, equals(1));
game.update(0); component.shouldRemove = true;
game.updateTree(0);
expect(game.children.isEmpty, equals(true)); expect(game.children.isEmpty, equals(true));
}); });
@ -174,7 +175,7 @@ void main() {
// Ensure clear does not remove components directly // Ensure clear does not remove components directly
expect(game.children.length, equals(3)); expect(game.children.length, equals(3));
game.update(0.0); game.updateTree(0);
expect(game.children.isEmpty, equals(true)); expect(game.children.isEmpty, equals(true));
}); });

View File

@ -80,8 +80,6 @@ class BulletComponent extends SpriteAnimationComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
y += bulletSpeed * dt; y += bulletSpeed * dt;
if (xDirection != 0) { if (xDirection != 0) {
x += bulletSpeed * dt * xDirection; x += bulletSpeed * dt * xDirection;

View File

@ -32,8 +32,6 @@ class EnemyComponent extends SpriteAnimationComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
y += enemySpeed * dt; y += enemySpeed * dt;
shouldRemove = destroyed || y >= gameRef.size.y; shouldRemove = destroyed || y >= gameRef.size.y;
} }

View File

@ -1,7 +1,6 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/geometry.dart'; import 'package:flame/geometry.dart';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:flame/timer.dart'; import 'package:flame/timer.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -10,7 +9,6 @@ import './bullet.dart';
import '../../game_stats/bloc/game_stats_bloc.dart'; import '../../game_stats/bloc/game_stats_bloc.dart';
import '../../inventory/bloc/inventory_bloc.dart'; import '../../inventory/bloc/inventory_bloc.dart';
import '../game.dart'; import '../game.dart';
import 'enemy.dart'; import 'enemy.dart';
import 'explosion.dart'; import 'explosion.dart';
@ -91,10 +89,7 @@ class PlayerComponent extends SpriteAnimationComponent
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
bulletCreator.update(dt); bulletCreator.update(dt);
shouldRemove = destroyed; shouldRemove = destroyed;
} }

View File

@ -28,7 +28,6 @@ class FlareActorComponent extends PositionComponent {
@override @override
@mustCallSuper @mustCallSuper
void update(double dt) { void update(double dt) {
super.update(dt);
flareAnimation.advance(dt); flareAnimation.advance(dt);
} }

View File

@ -27,7 +27,6 @@ class FlareParticle extends Particle {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
flareAnimation.advance(dt); flareAnimation.advance(dt);
} }
} }

View File

@ -51,8 +51,8 @@ class Ball extends BodyComponent {
} }
@override @override
@mustCallSuper
void update(double dt) { void update(double dt) {
super.update(dt);
_timeSinceNudge += dt; _timeSinceNudge += dt;
if (giveNudge) { if (giveNudge) {
giveNudge = false; giveNudge = false;

View File

@ -47,7 +47,6 @@ abstract class PositionBodyComponent<T extends Forge2DGame>
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
_updatePositionComponent(); _updatePositionComponent();
} }

View File

@ -51,7 +51,6 @@ class RiveComponent extends PositionComponent {
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
_renderer.advance(dt); _renderer.advance(dt);
} }
} }

View File

@ -18,14 +18,14 @@ extension FlameGameExtension on Component {
/// returned future to resolve. /// returned future to resolve.
Future<void> ensureAdd(Component component) async { Future<void> ensureAdd(Component component) async {
await add(component); await add(component);
update(0); updateTree(0);
} }
/// Makes sure that the [components] are added to the tree if you wait for the /// Makes sure that the [components] are added to the tree if you wait for the
/// returned future to resolve. /// returned future to resolve.
Future<void> ensureAddAll(Iterable<Component> components) async { Future<void> ensureAddAll(Iterable<Component> components) async {
await addAll(components); await addAll(components);
update(0); updateTree(0);
} }
} }