Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/flame/rendering/text_rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions packages/flame/lib/src/components/text_box_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,15 @@ class TextBoxComponent<T extends TextRenderer> 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;
}
}
29 changes: 29 additions & 0 deletions packages/flame/test/components/text_box_component_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down