stop an animation on a specific frame [solved]

Started by HandsFree, Tue 03/01/2017 23:46:33

Previous topic - Next topic

HandsFree

I want to stop an object animating when it reaches a certain frame.
I have in repeatedly execute:
Code: ags

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

morganw

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.

HandsFree

#2
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

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

In repexec
Code: ags

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?

morganw

If the function that starts it is called from repexec, is that before or after the "if (Lose)" check?

HandsFree

Before, but the function can also be called from other places. I tested it when not called from repexec and the same happens.

morganw

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.


Khris

Try this:

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



TheManInBoots

#9
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).

SMF spam blocked by CleanTalk