Launch animations in the background during the game

Started by Peegee, Tue 19/12/2023 08:46:41

Previous topic - Next topic

Peegee

Hello, I can not launch animations in the background effectively. The eNoblock function allows to keep the hand while an anim turns but also allows to launch the next anim at the same time, which must be problematic. For example, following a timer, I want to launch two animations in a row, two characters, but it does not launch the second, even if I put a timer per person.

How to best manage background animations?
 

Khris

It should work if you use timers, like this:

Code: ags
  // inside some function
  cNpc1.Animate(...);
  SetTimer(1, GetGameSpeed() * 5); // five seconds from now

  // inside room_RepExec()
  if (IsTimerExpired(1)) cNpc2.Animate(...);

Is this not working for you? If so, can you show your code and tell us exactly what's happening instead?

Peegee

Hello, yes, it does change something.
If I put the normal timer
Code: ags
SetTimer(1, 500);
...the character plays its animation in loop, although I put eOnce.
If I put
Code: ags
 
SetTimer (7, GetGameSpeed()*5);
He plays the anim only once but how to revive it only after a while? I don't really understand what this order does.
It also doesn't change the problem that I can't run another anim from another character in a row because of eNoBlock.
 

Khris

SetTimer() on its own doesn't really do anything, you also need to call IsTimerExpired() in a repeatedly_execute function.

If you want to chain multiple non-blocking animations, and have them run periodically, you might want to use a different approach.
One way is to simply count frames yourself:

Code: ags
int frames = 0;

bool AfterEvery(int after, int every) {
  int gs = GetGameSpeed();
  return (frames - gs * after) % (gs * every) == 0;
}

  // inside room_RepExec
  frames++;
  if (frames == GetGameSpeed() * 10000) frames = 0;

  if (AfterEvery(0, 5)) {
    // do something after 5, 10, 15, etc. seconds
  }
  if (AfterEvery(2, 5)) {
    // do something after 7, 12, 17, etc. seconds
  }

Untested!

Peegee

Hello, thank you for your reply
Of course, I trigger the animation following "IsTimerExpired", I know, I have already made a whole game (Gobliiins5).

However, I do not understand much about this code:
AfterEvery(int after, int every
 return (frames - gs * after) % (gs * every) == 0;

What's gs ? I never used that stuff.

What is AfterEvery ? A variable? I put where the animation? I did not find an explanation in the manual.

Snarky

Quote from: Peegee on Wed 20/12/2023 09:41:27I know, I have already made a whole game (Gobliiins5).

It's impressive that you were able to do that without really knowing how to code!

Quote from: Peegee on Wed 20/12/2023 09:41:27What's gs ? I never used that stuff.

gs is a variable that stores the value of GetGameSpeed(). Khris uses it just so he doesn't have to call GetGameSpeed() more than once in the next line.

Quote from: Peegee on Wed 20/12/2023 09:41:27What is AfterEvery ? A variable?

It's a function. By making a new function, it is easy to do something over and over. Here it just checks the value of frames in a way that will loop after a certain number of frames.

Quote from: Peegee on Wed 20/12/2023 09:41:27I put where the animation?

You put it where Khris has

Code: ags
// do something after 5, 10, 15, etc. seconds

and

Code: ags
// do something after 7, 12, 17, etc. seconds

(And as it says, this should be inside room_RepExec)

eri0o

Hey, just to check

Code: ags
cDog.LockView(VIEW_BARK);
cDog.Animate(0, 1, eOnce, eNoBlock); 
cCat.LockView(VIEW_ROAR);
cCat.Animate(0, 1, eOnce, eBlock);
cDog.UnlockView();
cCat.UnlockView(); 

Does this (adapt with your characters and views), works for playing the animation of the dog and the cat at the same time for you?

Peegee

Thanks for your answers. Yes, it works better now (with what I already know) but I have to put eNoBlock on both characters, to keep the interactivity. It is enough that I take into account the fact that the two anims of perso play at the same time in my views to obtain what I want.

I have never used LockView and unLockView. I imagine that doing a LockView automatically returns the basic anim of a person. Bye   

Khris

You said you don't really understand what SetTimer does, so excuse me for mentioning IsTimerExpired :P

Anyway, glad we could be of help :)

eri0o

@Peegee here is the manual page of LockView

https://adventuregamestudio.github.io/ags-manual/Character.html#characterlockview

If you use Animate method from an Character instance you should do so between LockView/UnlockView calls, otherwise there's no guarantee you will animate the view you think you are animating because AGS will be constantly running it's own per-character state machine and the character can change view because idling, blinking, walking, player in specific position, ... So you have to Lock. Only Room Objects don't require view locking because Room Objects don't have such state machine.

You would do LockView and then animate. Later, if you are waiting for a specific frame or timer or whatever method to know when the animation has ended, you do UnlockView.

Peegee

Ok, I understand, it can avoid some launching untimely animations.

SMF spam blocked by CleanTalk