How to wait until animation is done, but not using eBlock? - WORKAROUND

Started by johanvepa, Fri 30/09/2016 21:03:15

Previous topic - Next topic

johanvepa

Somewhere in my script I wisd to use an animation that does not block the whole script from continuing, but I would like some things to wait for the animation to end. Like, in my tower game I have this for whenever the character cAffald1 is hit and should first do its little death animation, then be placed somewhere else "out of the game".

Code: ags
function cAffald11_Look()
{
cAffald11.StopMoving();
cAffald11.ChangeView(2);
cAffald11.Animate(0, 4, eOnce, eNoBlock, eForwards);
a4.Play();
GiveScore(1);
bScore.Text = String.Format("%d", game.score);
cAffald11.x = 1;
cAffald11.y = 1;
}


What happens here is that cAffald1 moves to x=1, y=1 immediately and I cannot see its death animation. But if I use eBlock, then everything else stops, which is not good.

I could put something in rep_exec_always, but that seems and unsatisfactory solution to some other way to make the execution of function cAffald11_Look() simply wait its turn.

How to?

Jack

Repeat_exec is the way to go, generally.

Basically when the animation starts, you zero an integer counter. In repeat_exec, which runs every frame, you increment the counter by one and check the value. If the value is equal to or greater than (remember, you started counting from 0) the number of frames, the animation is done and you do what needs doing.

johanvepa

That was the idea. I just wondered if it was possible to avoid this.

Crimson Wizard

#3
Since your animation plays only once you could check for Character.Animating property in repeatedly_execute (or maybe even repeatedly_execute_always, as was suggested in another thread).
If there are multiple possible cases when character can animate and so you want to distinguish between them, also check for Character.View.

In other words, something like:
Code: ags

function repeatedly_execute_always()
{
   if (cAffald11.View == 2 && cAffald11.Loop == 0 && !cAffald11.Animating)
   {
       // animation just stopped
   }
}


If that does not work for some reason, alternative is to also check frame index:
Code: ags

if (cAffald11.View == 2 && cAffald11.Loop == 0 && cAffald11.Frame == (Game.GetFrameCountForLoop(2, 0) - 1))

But latter condition will trigger when the animation is at the last frame, not past it.

johanvepa

I was already at a solution with checking the frame property of the character in rep_exec. The question was if it was possible to avoid this. But no matter, I got a working solution now. Thank you both.

Crimson Wizard

#5
Quote from: Nanuaraq on Fri 30/09/2016 22:20:04
I was already at a solution with checking the frame property of the character in rep_exec. The question was if it was possible to avoid this.
Well, AGS does not support coroutines, so it is the usual way to do this.


EDIT: Hmm, did you try doing Wait(1) in the loop? I do not know if that will work for your game though:
Code: ags

while (cAffald11.Animating)
  Wait(1);

SMF spam blocked by CleanTalk