diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 2dd4d0eb117..d082e96c8a1 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -89,6 +89,12 @@ If you want to change the margins of the box use the `margins` variable in the ` Finally, if you want to simulate a "typing" effect, by showing each character of the string one by one as if being typed in real-time, you can provide the `boxConfig.timePerChar` parameter. +To control the typing effect, call `skip` to show the entire text at once, and `resetAnimation` to +reset the typing effect back to the beginning without having to recreate the component. Do note +that `skip` sets `boxConfig.timePerChar` to `0` so when attempting to replay the typing effect +after calling `skip`, make sure to re-set the `boxConfig.timePerChar` right before or after +calling `resetAnimation`. + Example usage: ```dart diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index 57550985d04..97473a4daa4 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -408,4 +408,15 @@ class TextBoxComponent extends TextComponent { void skip() { boxConfig = boxConfig.copyWith(timePerChar: 0); } + + /// Rewind the typewriter effect to start from the first character again. + /// + /// Useful for reusing this component when changing lines so that the next + /// line does not show immediately. + /// Also resets the [onComplete] call state which will be called again + /// when the line is finished. + void resetAnimation() { + _lifeTime = 0; + _isOnCompleteExecuted = false; + } } diff --git a/packages/flame/test/components/text_box_component_test.dart b/packages/flame/test/components/text_box_component_test.dart index 67c81ce94c5..d29f15513d8 100644 --- a/packages/flame/test/components/text_box_component_test.dart +++ b/packages/flame/test/components/text_box_component_test.dart @@ -219,6 +219,35 @@ lines.''', expect(textBoxComponent2.finished, true); }); + testWithFlameGame( + 'TextBoxComponent resets animation to the start of text', + ( + game, + ) async { + final textBoxComponent1 = TextBoxComponent( + text: 'aaa', + boxConfig: const TextBoxConfig(timePerChar: 1.0), + ); + await game.ensureAdd(textBoxComponent1); + // forward time by 2.5 seconds + game.update(2.5); + expect(textBoxComponent1.finished, false); + // flush + game.update(0.6); + expect(textBoxComponent1.finished, true); + // reset animation + textBoxComponent1.resetAnimation(); + // 'finished' state should reset immediately + expect(textBoxComponent1.finished, false); + expect(textBoxComponent1.currentChar, 0); + expect(textBoxComponent1.currentLine, 0); + game.update(2.5); + expect(textBoxComponent1.finished, false); + game.update(0.6); + expect(textBoxComponent1.finished, true); + }, + ); + testGolden( 'Alignment options', (game, tester) async {