Skip to content

Commit

Permalink
feat: Included completed completer in SpriteAnimation (#1564)
Browse files Browse the repository at this point in the history
  • Loading branch information
alestiago committed Apr 22, 2022
1 parent eff7279 commit 71999b1
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 3 deletions.
14 changes: 14 additions & 0 deletions doc/flame/components.md
Expand Up @@ -364,6 +364,20 @@ this.player = SpriteAnimationComponent.fromFrameData(
If you are not using `FlameGame`, don't forget this component needs to be updated, because the
animation object needs to be ticked to move the frames.

To listen when the animation is done (when it reaches the last frame and is not looping) you can
use `animation.completed`.

Example:

```dart
await animation.completed;
doSomething();
// or alternatively
animation.completed.whenComplete(doSomething);
```


## SpriteAnimationGroup

Expand Down
18 changes: 18 additions & 0 deletions packages/flame/lib/src/sprite_animation.dart
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:ui';

import 'assets/images.dart';
Expand Down Expand Up @@ -233,6 +234,8 @@ class SpriteAnimation {
/// Registered method to be triggered when the animation complete.
void Function()? onComplete;

Completer<void>? _completeCompleter;

/// The current frame that should be displayed.
SpriteAnimationFrame get currentFrame => frames[currentIndex];

Expand All @@ -243,6 +246,20 @@ class SpriteAnimation {
/// still image).
bool get isSingleFrame => frames.length == 1;

/// A future that will complete when the animation completes.
///
/// An animation is considered to be completed if it reaches its [isLastFrame]
/// and is not [loop]ing.
Future<void> get completed {
if (_done) {
return Future.value();
}

_completeCompleter ??= Completer<void>();

return _completeCompleter!.future;
}

/// Sets a different step time to each frame.
/// The sizes of the arrays must match.
set variableStepTimes(List<double> stepTimes) {
Expand Down Expand Up @@ -307,6 +324,7 @@ class SpriteAnimation {
} else {
_done = true;
onComplete?.call();
_completeCompleter?.complete();
return;
}
} else {
Expand Down
74 changes: 71 additions & 3 deletions packages/flame/test/sprite_animation_test.dart
Expand Up @@ -44,9 +44,12 @@ void main() {
test('onComplete called for single-frame animation', () {
var counter = 0;
final sprite = MockSprite();
final animation =
SpriteAnimation.spriteList([sprite], stepTime: 1, loop: false)
..onComplete = () => counter++;
final animation = SpriteAnimation.spriteList(
[sprite],
stepTime: 1,
loop: false,
)..onComplete = () => counter++;

expect(counter, 0);
animation.update(0.5);
expect(counter, 0);
Expand All @@ -55,6 +58,71 @@ void main() {
animation.update(1);
expect(counter, 1);
});

test('completed completes', () {
final sprite = MockSprite();
final animation = SpriteAnimation.spriteList(
[sprite],
stepTime: 1,
loop: false,
);

expectLater(animation.completed, completes);

animation.update(1);
});

test(
'completed completes when the animation has already completed',
() async {
final sprite = MockSprite();
final animation = SpriteAnimation.spriteList(
[sprite],
stepTime: 1,
loop: false,
);

animation.update(1);

expectLater(animation.completed, completes);
},
);

test(
"completed doesn't complete when the animation is yet to complete",
() async {
final sprite = MockSprite();
final animation = SpriteAnimation.spriteList(
[sprite],
stepTime: 1,
loop: false,
);

expectLater(animation.completed, doesNotComplete);
},
);

test(
"completed doesn't complete when animation is looping",
() async {
final sprite = MockSprite();
final animation = SpriteAnimation.spriteList([sprite], stepTime: 1);

expectLater(animation.completed, doesNotComplete);
},
);

test(
"completed doesn't complete when animation is looping and on last frame",
() async {
final sprite = MockSprite();
final animation = SpriteAnimation.spriteList([sprite], stepTime: 1);

animation.update(1);

expectLater(animation.completed, doesNotComplete);
},
);
});
}

Expand Down

0 comments on commit 71999b1

Please sign in to comment.