Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: HandsFree on Tue 03/01/2017 23:46:33

Title: stop an animation on a specific frame [solved]
Post by: HandsFree on Tue 03/01/2017 23:46:33
I want to stop an object animating when it reaches a certain frame.
I have in repeatedly execute:
Code (ags) Select

if (oWOF.Frame == iLow - 1){
    oWOF.StopAnimating();
    //and other things
}

But the animation only stops at the last frame.
The command to start animating is in a function that is also called from repexec, if that matters.

How should I do this?
thanks
Title: Re: stop an animation on a specific frame.
Post by: morganw on Tue 03/01/2017 23:59:49
That looks correct to me, so I would guess that either iLow doesn't have the value you are expecting, or your other function (that starts animating it) is re-starting it. You might want to check Object.Animating as part of the stop or start function, to make sure it's in the state that you are expecting.
Title: Re: stop an animation on a specific frame.
Post by: HandsFree on Wed 04/01/2017 00:22:16
Found what the problem is, but don't know how to fix it.
The function that starts the animation also sets a boolean 'Lose' to true, and that is tested in repexec.
But apparently the Lose isn't true until the function is finished.

In the function that starts animating:
Code (ags) Select

oWOF.Animate(iHigh, 15, eOnce, eBlock);
Lose = true;
oWOF.Animate(iHigh, 15, eOnce, eBlock, eBackwards);

In repexec
Code (ags) Select

if (Lose){
  if (oWOF.Frame == iLow - 1){
    oWOF.StopAnimating();
  }
}


So when the frame to stop is reached, 'Lose' is still false apparently.
How to fix this?
Title: Re: stop an animation on a specific frame.
Post by: morganw on Wed 04/01/2017 00:30:04
If the function that starts it is called from repexec, is that before or after the "if (Lose)" check?
Title: Re: stop an animation on a specific frame.
Post by: HandsFree on Wed 04/01/2017 00:31:51
Before, but the function can also be called from other places. I tested it when not called from repexec and the same happens.
Title: Re: stop an animation on a specific frame.
Post by: morganw on Wed 04/01/2017 00:52:45
I think it's a side effect of using a blocking function, so until the blocking is finished, "Lose" isn't checked. If you move the check into repeatedly_execute_always (before frame has changed) or late_repeatedly_execute_always (after frame has changed), that should make the check happen during the animation and find your target frame. I've not tested it, but I assume that stopping a blocking animation will unblock the function and let everything continue as normal.

Alternatively, I think you'd have to move away from calling blocking animations and implement your own checks as to what is animating, which might be more complicated initially, but you know your variables will update on every engine step.
Title: Re: stop an animation on a specific frame.
Post by: HandsFree on Wed 04/01/2017 01:16:18
Hmm, tried repexec_always and it still doesn't work. :~(
Title: Re: stop an animation on a specific frame.
Post by: Khris on Wed 04/01/2017 01:26:29
Try this:

  oWOF.Animate(iHigh, 15, eOnce, eBlock);
  oWOF.Animate(iHigh, 15, eOnce, eNoBlock, eBackwards);
  while (oWOF.Frame != iLow - 1) {
    Wait(1);
  }
  oWOF.StopAnimating();

Title: Re: stop an animation on a specific frame.
Post by: HandsFree on Wed 04/01/2017 01:39:29
That worked. :)
thanks
Title: Re: stop an animation on a specific frame [solved]
Post by: TheManInBoots on Tue 17/09/2019 17:40:14
I just want to add another solution even though this has been posted long ago, in case someone else encounters a similar problem, because there's a simpler solution, this one:


if(oWOF.Frame==iLow-1)
{oWOF.SetView(oWOF.View, oWOF.Loop, oWOF.Frame);}


The function setup

object.SetView(object.View, object.Loop, object.Frame);

will freeze the animation at the current view frame. You can use the same principle for characters with the LockViewframe function.


And to the one unanswered question, Handsfree, or anyone interested, one way to start an animation at a specific frame is by getting a dummy object, set it to the same frame, position (, scaling, etc.) that the main object is on that you want to animate.
Then set the main object's Visibility to false and animate it.
Using the function above in repeatedly execute, as soon as the invisible main object is on the frame that you want it to start animating, you set its Visibility back to true, and make the dummy object transparent.

The same principle applies to characters, using the LockViewFrame function and the Transparency value (100 for not Visible and 0 for Visible).