When using testWidgets to test pages/widgets that renders a game, one may test a widget in a state after the game has loaded.
This introduces toBeLoaded method to be called by widget tests that evaluate things that happens after the game "onLoad" cycle.
await tester.pumpWidget(GameWidget(game: game));
await game.toBeLoaded(); // ⚠️ calling this before pumping the game into a gameWidget throws assertion error.
await tester.pump();
This PR adds a new event system based on the componentsAtPoint delivery mechanism. These events allow for a proper support of components that implement renderTree() method. The CameraComponent is one such component, with more planned in the future.
Additionally, the following improvements compared to the current tap events added:
- the same component can be tapped with multiple fingers simultaneously;
- a component that received onTapDown is guaranteed to receive onTapUp or onTapCancel later;
- a component that moves away from the point of touch will receive onTapCancel instead of onTapUp (even though the game widget receives onTapUp from Flutter).
Due to the fact that the switch from the current event system to the new event system is potentially a significant breaking change, the new event system is introduced as parallel to the existing one. This way we have more time to test the new system before recommending the switch and deprecating the old one; and the switch itself should feel more gradual.
Changes _renderFixtures to renderFixture. This keeps the consistency with the other public render methods in BodyComponent.
Introduces new functionalities:
Allow listening when a given fixture is rendered
Allows modifying the rendering logic for a given (one or more) fixtures.
For example, avoiding a fixture to be rendered:
class MyBodyComponent extends BodyComponent { ... void renderFixture(Canvas canvas, Fixture fixture) { final avoidRendering = condition; // Any condition here. if (avoidRendering) return; super.renderFixture(canvas, fixture); } ... }
Created a mixin to handle the margin to the viewport, mostly to remove the code duplication in ButtonComponent and HudButtonComponent, but it can also be useful in other cases when you don't want to wrap your component in HudMarginComponent.
Once the new camera system is in place this will of course have to be replaced.
- Added option align in the TextBoxComponent which controls the alignment of text.
- Added option for the TextBoxComponent to have a fixed size (before the only mode was for the textbox to automatically expand/shrink to fit the text).
This PR adds [SpriteFontRenderer], which is a new implementation of [TextRenderer], allowing to render text based on fonts embedded into a spritesheet.
See the T-Rex game example, where the score is now rendered based on a spritesheet font.
(Also added highscore tracking for the TRex game).
* Add onFinishCallback as optional parameter
* Rename onFinishCallback to onComplete
* Add void return for onComplete
* Add deprecated getter and setter for onFinishCallback
* Use named onComplete parameter
* Add version in which onFinishCallback will be removed
At first, In #1667, I was planning to change only SpriteWidget to be able to remove showing LoadingBuilder when non-future sprite was passed.
But after some digging, I found that BaseFutureBuilder causes the loading because it only accepts Future as a parameter.
And BaseFutureBuilder are the very base of all image-related widgets such as NineTileBoxWidget, SpriteAnimationWidget, ... etc.
So the key point of this change should allow BaseFutureBuilder to FutureOr as a parameter and split the build function according to the parameter type.
After #1645, the Default constructor of SpriteButton can pass Future but its constructor is not consistent with other image-related widgets.
Plus, type of FutureOr<List<Sprite>> _buttonsFuture only compatible with Future<List<Sprite>> but not List<Sprite>.
So I added secondary constructor SpriteButton.future that accepts only Future and Replaced the FutureOr<Sprite> to Sprite in the default constructor.
Adding a helper function for solving quadratic equations.
This allows simplifying logic in CircleComponent, but can also be used in other places later on.
Also, the logic in CircleComponent was simplified to avoid unnecessary line.containsPoint.