mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-31 08:56:01 +08:00 
			
		
		
		
	Introduce updateTree (#1158)
* Introduce updateTree * Update tests * Fix update for game-in-game situations * Add dartdoc to updateTree
This commit is contained in:
		| @ -72,7 +72,6 @@ class MovableEmber extends Ember<FollowComponentExample> | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     final deltaPosition = velocity * (speed * dt); | ||||
|     position.add(deltaPosition); | ||||
|     positionText.text = '(${x.toInt()}, ${y.toInt()})'; | ||||
|  | ||||
| @ -52,7 +52,6 @@ class MyCollidable extends PositionComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     if (_isWallHit) { | ||||
|       removeFromParent(); | ||||
|       return; | ||||
|  | ||||
| @ -89,7 +89,6 @@ class AnimatedComponent extends SpriteAnimationComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     position += velocity * dt; | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -121,7 +121,6 @@ abstract class MyCollidable extends PositionComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     if (_isDragged) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| import 'package:flame/components.dart'; | ||||
| import 'package:flame/game.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 | ||||
| // draggable component to this game. | ||||
| @ -32,8 +35,15 @@ class ComposabilityExample extends FlameGame with HasDraggables { | ||||
| } | ||||
|  | ||||
| class ParentSquare extends RectangleComponent with HasGameRef { | ||||
|   static final defaultPaint = BasicPalette.white.paint() | ||||
|     ..style = PaintingStyle.stroke; | ||||
|  | ||||
|   ParentSquare(Vector2 position, Vector2 size) | ||||
|       : super(position: position, size: size); | ||||
|       : super( | ||||
|           position: position, | ||||
|           size: size, | ||||
|           paint: defaultPaint, | ||||
|         ); | ||||
|  | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
| @ -49,21 +59,25 @@ class ParentSquare extends RectangleComponent with HasGameRef { | ||||
|         position: Vector2(100, 100), | ||||
|         size: childSize, | ||||
|         angle: 2, | ||||
|         paint: defaultPaint, | ||||
|       ), | ||||
|       RectangleComponent.square( | ||||
|         position: Vector2(160, 100), | ||||
|         size: childSize, | ||||
|         angle: 3, | ||||
|         paint: defaultPaint, | ||||
|       ), | ||||
|       RectangleComponent.square( | ||||
|         position: Vector2(170, 150), | ||||
|         size: childSize, | ||||
|         angle: 4, | ||||
|         paint: defaultPaint, | ||||
|       ), | ||||
|       RectangleComponent.square( | ||||
|         position: Vector2(70, 200), | ||||
|         size: childSize, | ||||
|         angle: 5, | ||||
|         paint: defaultPaint, | ||||
|       ), | ||||
|     ]; | ||||
|  | ||||
|  | ||||
| @ -61,8 +61,6 @@ class LogoComponent extends SpriteComponent with HasGameRef<DebugExample> { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|  | ||||
|     x += xDirection * speed * dt; | ||||
|  | ||||
|     final rect = toRect(); | ||||
|  | ||||
| @ -23,7 +23,6 @@ class JoystickPlayer extends SpriteComponent with HasGameRef { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     if (!joystick.delta.isZero()) { | ||||
|       position.add(joystick.relativeDelta * maxSpeed * dt); | ||||
|       angle = joystick.delta.screenAngle(); | ||||
|  | ||||
| @ -570,7 +570,6 @@ class TrafficLightComponent extends Component { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     colorChangeTimer.update(dt); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| ## [Next] | ||||
|  - Add `ButtonComponent` backed by two `PositionComponent`s | ||||
|  - Add `SpriteButtonComponent` backed by two `Sprite`s | ||||
|  - Introduce `updateTree` to follow the `renderTree` convention | ||||
|  - Fix `Parallax.load` with different loading times | ||||
|  | ||||
| ## [1.0.0-releasecandidate.18] | ||||
|  | ||||
| @ -122,10 +122,19 @@ class Component with Loadable { | ||||
|   /// your state considering this. | ||||
|   /// 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. | ||||
|   @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.forEach((c) => c.update(dt)); | ||||
|     if (callOwnUpdate) { | ||||
|       update(dt); | ||||
|     } | ||||
|     children.forEach((c) => c.updateTree(dt)); | ||||
|   } | ||||
|  | ||||
|   void render(Canvas canvas) {} | ||||
|  | ||||
| @ -91,7 +91,6 @@ class JoystickComponent extends HudMarginComponent with Draggable { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     final knobRadius2 = knobRadius * knobRadius; | ||||
|     delta.setFrom(_unscaledDelta); | ||||
|     if (delta.isZero() && _baseKnobPosition != knob!.position) { | ||||
|  | ||||
| @ -100,7 +100,6 @@ class ParallaxComponent<T extends FlameGame> extends PositionComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     parallax?.update(dt); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -31,7 +31,6 @@ class ParticleComponent extends Component { | ||||
|   /// Passes update chain to child [Particle]. | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     particle.update(dt); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -100,7 +100,6 @@ class SpriteAnimationComponent extends PositionComponent with HasPaint { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     if (playing) { | ||||
|       animation?.update(dt); | ||||
|     } | ||||
|  | ||||
| @ -111,7 +111,6 @@ class SpriteAnimationGroupComponent<T> extends PositionComponent with HasPaint { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     animation?.update(dt); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -232,7 +232,6 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     _lifeTime += dt; | ||||
|     if (_previousChar != currentChar) { | ||||
|       redraw(); | ||||
|  | ||||
| @ -39,7 +39,6 @@ class TimerComponent extends Component { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     timer.update(dt); | ||||
|  | ||||
|     if (removeOnFinish && timer.finished) { | ||||
|  | ||||
| @ -64,10 +64,7 @@ class FlameGame extends Component with Game { | ||||
|   /// interfering with each others rendering. | ||||
|   @override | ||||
|   @mustCallSuper | ||||
|   void render(Canvas canvas) { | ||||
|     super.render(canvas); | ||||
|     _cameraWrapper.render(canvas); | ||||
|   } | ||||
|   void render(Canvas canvas) => _cameraWrapper.render(canvas); | ||||
|  | ||||
|   /// This updates every component in the tree. | ||||
|   /// | ||||
| @ -78,7 +75,9 @@ class FlameGame extends Component with Game { | ||||
|   @override | ||||
|   @mustCallSuper | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     if (parent == null) { | ||||
|       super.updateTree(dt, callOwnUpdate: false); | ||||
|     } | ||||
|     _cameraWrapper.update(dt); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -18,13 +18,11 @@ class _MyTap extends PositionComponent with Tappable { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     updated = true; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void render(Canvas canvas) { | ||||
|     super.render(canvas); | ||||
|     rendered = true; | ||||
|   } | ||||
|  | ||||
| @ -78,12 +76,12 @@ void main() { | ||||
|  | ||||
|       await wrapper.add(child); | ||||
|       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); | ||||
|  | ||||
|       wrapper.remove(child); | ||||
|       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); | ||||
|     }); | ||||
|  | ||||
| @ -98,7 +96,7 @@ void main() { | ||||
|         expect(wrapper.contains(child), false); | ||||
|         await future; | ||||
|         expect(wrapper.contains(child), false); | ||||
|         wrapper.update(0); | ||||
|         wrapper.updateTree(0); | ||||
|         expect(wrapper.contains(child), true); | ||||
|       }, | ||||
|     ); | ||||
|  | ||||
| @ -30,7 +30,6 @@ class _MyComponent extends PositionComponent with HasGameRef { | ||||
| 
 | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     isUpdateCalled = true; | ||||
|   } | ||||
| 
 | ||||
| @ -159,9 +158,11 @@ void main() { | ||||
| 
 | ||||
|   flameGame.test('removes PositionComponent when shouldRemove is true', | ||||
|       (game) async { | ||||
|     await game.ensureAdd(PositionComponent()..shouldRemove = true); | ||||
|     final component = PositionComponent(); | ||||
|     await game.ensureAdd(component); | ||||
|     expect(game.children.length, equals(1)); | ||||
|     game.update(0); | ||||
|     component.shouldRemove = true; | ||||
|     game.updateTree(0); | ||||
|     expect(game.children.isEmpty, equals(true)); | ||||
|   }); | ||||
| 
 | ||||
| @ -174,7 +175,7 @@ void main() { | ||||
| 
 | ||||
|     // Ensure clear does not remove components directly | ||||
|     expect(game.children.length, equals(3)); | ||||
|     game.update(0.0); | ||||
|     game.updateTree(0); | ||||
|     expect(game.children.isEmpty, equals(true)); | ||||
|   }); | ||||
| 
 | ||||
| @ -80,8 +80,6 @@ class BulletComponent extends SpriteAnimationComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|  | ||||
|     y += bulletSpeed * dt; | ||||
|     if (xDirection != 0) { | ||||
|       x += bulletSpeed * dt * xDirection; | ||||
|  | ||||
| @ -32,8 +32,6 @@ class EnemyComponent extends SpriteAnimationComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|  | ||||
|     y += enemySpeed * dt; | ||||
|     shouldRemove = destroyed || y >= gameRef.size.y; | ||||
|   } | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| import 'package:flame/components.dart'; | ||||
| import 'package:flame/geometry.dart'; | ||||
| import 'package:flame/input.dart'; | ||||
|  | ||||
| import 'package:flame/timer.dart'; | ||||
| import 'package:flame_bloc/flame_bloc.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
| @ -10,7 +9,6 @@ import './bullet.dart'; | ||||
| import '../../game_stats/bloc/game_stats_bloc.dart'; | ||||
| import '../../inventory/bloc/inventory_bloc.dart'; | ||||
| import '../game.dart'; | ||||
|  | ||||
| import 'enemy.dart'; | ||||
| import 'explosion.dart'; | ||||
|  | ||||
| @ -91,10 +89,7 @@ class PlayerComponent extends SpriteAnimationComponent | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|  | ||||
|     bulletCreator.update(dt); | ||||
|  | ||||
|     shouldRemove = destroyed; | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -28,7 +28,6 @@ class FlareActorComponent extends PositionComponent { | ||||
|   @override | ||||
|   @mustCallSuper | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     flareAnimation.advance(dt); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -27,7 +27,6 @@ class FlareParticle extends Particle { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     flareAnimation.advance(dt); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -51,8 +51,8 @@ class Ball extends BodyComponent { | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   @mustCallSuper | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     _timeSinceNudge += dt; | ||||
|     if (giveNudge) { | ||||
|       giveNudge = false; | ||||
|  | ||||
| @ -47,7 +47,6 @@ abstract class PositionBodyComponent<T extends Forge2DGame> | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     _updatePositionComponent(); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -51,7 +51,6 @@ class RiveComponent extends PositionComponent { | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
|     super.update(dt); | ||||
|     _renderer.advance(dt); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -18,14 +18,14 @@ extension FlameGameExtension on Component { | ||||
|   /// returned future to resolve. | ||||
|   Future<void> ensureAdd(Component component) async { | ||||
|     await add(component); | ||||
|     update(0); | ||||
|     updateTree(0); | ||||
|   } | ||||
|  | ||||
|   /// Makes sure that the [components] are added to the tree if you wait for the | ||||
|   /// returned future to resolve. | ||||
|   Future<void> ensureAddAll(Iterable<Component> components) async { | ||||
|     await addAll(components); | ||||
|     update(0); | ||||
|     updateTree(0); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Lukas Klingsbo
					Lukas Klingsbo