Minor animation improvements

- Bind nextFrame to window.requestAnimationFrame to prevent hanging if the tab is out of focus
- Playing an animation when one is already queued/in progress now cancels the old one instead of throwing an error
This commit is contained in:
Elijah R 2024-07-20 08:32:09 -04:00
parent 067a3ff369
commit a075010a96

View file

@ -24,6 +24,7 @@ function randint(min: number, max: number) {
class AgentAnimationState { class AgentAnimationState {
char: Agent; char: Agent;
anim: AcsAnimation; anim: AcsAnimation;
private cancelled: boolean = false;
finishCallback: () => void; finishCallback: () => void;
frameIndex = 0; frameIndex = 0;
@ -41,7 +42,14 @@ class AgentAnimationState {
this.nextFrame(); this.nextFrame();
} }
cancel() {
this.cancelled = true;
clearTimeout(this.interval);
}
nextFrame() { nextFrame() {
requestAnimationFrame(() => {
if (this.cancelled) return;
this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]); this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]);
if (this.frameIndex >= this.anim.frameInfo.length) { if (this.frameIndex >= this.anim.frameInfo.length) {
@ -53,6 +61,7 @@ class AgentAnimationState {
this.interval = setTimeout(() => { this.interval = setTimeout(() => {
this.nextFrame(); this.nextFrame();
}, this.anim.frameInfo[this.frameIndex].frameDuration * 10); }, this.anim.frameInfo[this.frameIndex].frameDuration * 10);
});
} }
} }
@ -350,7 +359,10 @@ export class Agent {
// add promise versions later. // add promise versions later.
playAnimation(index: number, finishCallback: () => void) { playAnimation(index: number, finishCallback: () => void) {
if (this.animState != null) throw new Error('Cannot play multiple animations at once.'); if (this.animState != null) {
this.animState.cancel();
this.animState = null;
}
let animInfo = this.data.animInfo[index]; let animInfo = this.data.animInfo[index];
// Create and start the animation state // Create and start the animation state