Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: daniel on Mon 15/05/2017 19:32:48

Title: animating mutliple things at the same time
Post by: daniel on Mon 15/05/2017 19:32:48
hi,

i'm trying to animate my 2-part logo on the title screen.

what i'd like to do is:
1. fade in the BG from black. (i'm using a black object and fade it to 100% transparency because i couldn't get the FadeIn and FadeOut to work without the BG flashing on the screen for a second at the start)
2. fade in the main logo
3. once the main logo is at 50% transparency start fading in the second part of the logo while it's moving down into position along Y

when i put this code into function room_RepExec() it just executes one command after the another:

int BlackoutTrans = oBlackout.Transparency;
int LogoTrans = oLogo.Transparency;
int LogoExtraTrans = oLogoExtra.Transparency;

  while (BlackoutTrans < 100){
    BlackoutTrans++;
    oBlackout.Transparency = BlackoutTrans;
    Wait(1);
  }
   
  while ((BlackoutTrans == 100)&&(LogoTrans > 0)){
    LogoTrans--;
    oLogo.Transparency = LogoTrans;
    Wait(1);
  }
 
  while ((LogoTrans < 50)&&(LogoExtraTrans > 0)){
    LogoExtraTrans--;
    oLogoExtra.Transparency = LogoExtraTrans;
    Wait(1);
  }
 
  while ((LogoTrans < 50)&&(oLogoExtra.Y < 30)){
    oLogoExtra.Y++;
    Wait(1);
  }


how can i execute all of these at the same time without them blocking each other?
when i use "if" instead of "when" the script stops after the blackout is at 100% transparency.
so, once again my noob skills have failed me...

cheers
Title: Re: animating mutliple things at the same time
Post by: dayowlron on Mon 15/05/2017 20:23:36
Basically what you need to do is have one loop with conditions to determine at what part of the animation your at.
I am not sure of what you wanting specifically but I can code something up for you if you like. You also don't need variables to contain the transparency as that is a property of the object anyways.
For instance:

int BlackoutTrans=oBlackout.Transparency;
BlackoutTrans++;
oBlackout.Transparency = BlackoutTrans;

is the same as

oBlackout.Transparency ++;
Title: Re: animating mutliple things at the same time
Post by: dayowlron on Mon 15/05/2017 20:32:26
Try this:

    while (oLogoExtra.Transparency>0) {
        if (oBlackout.Transparency<100) oBlackout.Transparency++;
        if (oLogo.Transparency>0) oLogo.Transparency--;
        if (oLogo.Transparency<50) {
            oLogoExtra.Transparency--;
            if (oLogoExtra.Y<30) oLogoExtra.Y ++;
        }
        wait(1);
    }
Title: Re: animating mutliple things at the same time
Post by: abstauber on Mon 15/05/2017 20:45:36
Also for this kind of stuff, try the Tween Module. It makes your life considerably easier and also handles transparency transitions.
Title: Re: animating mutliple things at the same time
Post by: Khris on Mon 15/05/2017 22:05:08
IIRC, changing the transparency directly wasn't reliable for some reason; the preferred method is to change a variable, then set the transparency to that.

With that out of the way, the idea is to basically plan a timeline.
Frames
0-------------------100---------150---------200-----------250--------->
|<- fade out black ->|
                     |<- fade in LogoTrans ->|
                                  | <- fade in LogoExtra ->|
We end up with this:

int clamp(int a) {
  if (a < 0) return 0;
  if (a > 100) return 100;
  return a;
}

int frames = 0;
function room_RepExec() {
  oBlackout.Transparency = clamp(frames); // 0 -> 100, starting @ frame 0
  oLogo.Transparency = clamp(200 - frames); // 100 -> 0, starting @ frame 100
  oLogoExtra.Transparency = clamp(250 - frames); // 100 -> 0, starting @ frame 150
  if (frames < 400) frames++;
}
Title: Re: animating mutliple things at the same time
Post by: Snarky on Tue 16/05/2017 00:01:16
Quote from: abstauber on Mon 15/05/2017 20:45:36
Also for this kind of stuff, try the Tween Module. It makes your life considerably easier and also handles transparency transitions.

So much this!

Code (ags) Select
function room_AfterFadein()
{
  oBlackout.TweenFadeOut(2.5);  // Fade to transparent over 2.5 seconds = 100 cycles

  oLogo.TweenFadeIn(2.5, eEaseLinearTween, eNoBlockTween);          // Non-blocking, so run the next tween in parallel
  oLogoExtraTweenFadeIn(2.5, eEaseLinearTween, eBlockTween, 1.25);  // Delay start of tween by 1.25 seconds = 50 cycles
}
Title: Re: animating mutliple things at the same time
Post by: daniel on Tue 16/05/2017 00:05:51
thanks guys,

@dayowlron
i tried your solution and the result is similar to what i get if i just used "if" statements...the BG fades in and then nothing more happens

@Khris
your solution works, however it's still missing the downward movement for "oLogoExtra" from 0 to 30 along the Y axis...also it seems to me it's very tricky to adjust animation speed for each element using this method?

@abstauber
thanks for the recommendation. i'm gonna take a look at that module...it sounds pretty neat.

EDIT:
got it. thanks for the code snarky.
i just added this to tween the logoExtra along the Y...also had to set the fadeIn to noBlock
oLogoExtra.TweenY(2.5, 30, eEaseInOutSineTween, eNoBlockTween, 1.25);
Title: Re: animating mutliple things at the same time
Post by: daniel on Wed 17/05/2017 17:29:11
hey guys,

i've hit another snag and this question is kind of related so i'll just post it here and hope somebody will find it:D

anyway i have multiple animations in a background that i would like to tween (TweenImage) in order to make them look smoother.
however since these are endless loops i tried placing them in "function room_RepExec()" like this:


  oGlitter.TweenImage(oGlitterEmpty, 0.5, 377, eEaseLinearTween, eBlockTween);
  oGlitter.TweenImage(oGlitterEmpty, 0.5, 378, eEaseLinearTween, eBlockTween);
  oGlitter.TweenImage(oGlitterEmpty, 0.5, 379, eEaseLinearTween, eBlockTween);
  oGlitter.TweenImage(oGlitterEmpty, 0.5, 376, eEaseLinearTween, eBlockTween);

  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 383, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 384, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 385, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 386, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 387, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 388, eEaseLinearTween, eBlockTween);
  oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 382, eEaseLinearTween, eBlockTween);


which of course doesn't work since one animation is blocking the other and they run in sequence instead of simultaneously.
i tried using "eNoBlockTween" with delays set for each tween and somehow setting a variable to check if a tween is playing but failed completely.
i also tried setting it up outside of "function room_RepExec()" using tween delays and a timer...couldn't get that to work either:(

any ideas?
Title: Re: animating mutliple things at the same time
Post by: Cassiebsg on Wed 17/05/2017 18:29:19
I'm not familiar with the tween module this much, but have you tried to set all tweens but the last to NoBlock? Usually works for normal animations, so maybe it'll work with the tween too?
Title: Re: animating mutliple things at the same time
Post by: daniel on Wed 17/05/2017 19:44:49
Quote from: Cassiebsg on Wed 17/05/2017 18:29:19
I'm not familiar with the tween module this much, but have you tried to set all tweens but the last to NoBlock? Usually works for normal animations, so maybe it'll work with the tween too?

thanks cassiebsg,

yes i've tried that and it doesn't work unfortunately. i'm a total noob myself but i think the problem is that, if there is no block or some kind of variable that switches the tweens on and off the RepExec just keeps spawning new tweens every frame. so basically you don't see anything happening because none of the tweens (other than the ones with the block set) are ever executed before the next one gets thrown on top.
also the game then crashes because it's exceeding the 64 tweens limit...
Title: Re: animating mutliple things at the same time
Post by: Cassiebsg on Wed 17/05/2017 19:50:22
Are you running these inside an if?
You need to, to avoid them being run from the start every loop.  :-\

You need to tell AGS to only run the code IF it's not running, otherwise ignore it.
Title: Re: animating mutliple things at the same time
Post by: Khris on Wed 17/05/2017 20:05:53
You need to keep track of the game state (here: your objects' sprites) using variables. Then you need to think about how and when to advance the state.
And you cannot use a blocking command for background animations, ever.

The idea here is to either set timers or count frames, then advance the object(s) to the next sprite.

int glitterFrame = 0, smokeFrame = 0;

function room_RepExec() {
  if (IsTimerExpired(1)) {
    glitterFrame = (glitterFrame + 1) % 4; // 0 - 3
    smokeFrame = (smokeFrame + 1) % 7; // 0 - 6
    oGlitter.TweenImage(oGlitterEmpty, 0.5, 376 + glitterFrame, eEaseLinearTween, eNoBlockTween);
    oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 382 + smokeFrame, eEaseLinearTween, eNoBlockTween);
    SetTimer(1, GetGameSpeed() / 2); // half a second to next frame
  }
}


Start the animations by calling SetTimer(1, 1); in after fadein.

It's also possible to change this code to use a specific view loop; that way you can simply set the sprites in the view editor without having to worry about the number of frames or their sequence.
Title: Re: animating mutliple things at the same time
Post by: daniel on Wed 17/05/2017 20:32:53
thanks chris,

i'll give this a try as soon as i get the time...

i hate to be a bother but could you explain to me briefly what the "%" remainder does in the code?
i looked in the AGS help but didn't find anything...
Title: Re: animating mutliple things at the same time
Post by: Snarky on Wed 17/05/2017 20:46:44
% is the modulo operator, which gives you the remainder of an integer division: the part of the first number that can't be divided by the second number. So 7 % 3 = 1, because 7/3 = 2 (in integer division â€" meaning you can only fit 3 two times in seven), with a remainder of 1 (because 2*3 = 6 and 7-6 = 1).

Another way to think about it is that the remainder is the fractional part of the division. So if the integer division 7/3=2 gives you the integer part of the answer, 7%3=1 gives you the fractional part: put them together, and you get 7/3 = 2 + 1/3.

The cool thing about the modulo is that taking a number % N leaves you with a remainder that is guaranteed to be between 0 and N-1. For example, consider modulo 10:

0 % 10 = 0 (0 / 10 = 0 with a remainder of 0)
1 % 10 = 1 (1 / 10 = 0 with a remainder of 1)
...
9 % 10 = 9
10 % 10 = 0 (because 10/10 = 1 with no remainder)
11 % 10 = 1
...
19 % 10 = 9
20 % 10 = 0
21 % 10 = 1
...

A number modulo 10, then, is just the last digit of that number, cycling 0-9 for ever. Similarly, taking the number sequence modulo 8 will give you a repeating 0-7 cycle. This is a very useful property for making loops.
Title: Re: animating mutliple things at the same time
Post by: daniel on Wed 17/05/2017 20:55:41
thanks snarky!
i'm not 100% sure i understood the maths behind it but at least now i know what it does:)
Title: Re: animating mutliple things at the same time
Post by: Snarky on Wed 17/05/2017 21:07:02
OK, let's put it like this: Let's say you have 23 comic books that you want to give away to four cousins. They can't share, and if they don't all get exactly the same number they'll fight.

Q1: How many comics does each cousin get?
This is integer division, and the answer is five. (You have enough to give each cousin five comics each, but not enough to give them each six.)
23/4 = 5

Q2: How many comics are you left with?
This is the remainder, and in this case the answer is three, because if you give four cousins five comics each, you've given away 20 and are left with 3.
23%4 = 3

The number of comics you're left with will always be between 0 and 3, because if you were left with 4 comics or more you could just give them each another one.

Make sense?
Title: Re: animating mutliple things at the same time
Post by: Khris on Wed 17/05/2017 21:08:10
You can also visualize it using a table. Here's the table for % 4:
 0  1  2  3
4  5  6  7
8  9 10 11
12 13 14 15
16 17 18 19
20 21 ...
Pick any number x, and x % 4 results in the first row's number of the same column.
Title: Re: animating mutliple things at the same time
Post by: daniel on Thu 18/05/2017 10:24:59
thanks guys, i think i got it now
i've always been more of a "right hemisphere of the brain" kind of guy:D
Title: Re: animating mutliple things at the same time
Post by: Snarky on Thu 18/05/2017 10:42:44
Khris's table also leads to another way to think of it: if you have a wheel with N number of spaces (e.g. wheel of fortune, roulette, combination safe), which we'll label sequentially from 0 to N-1, and you spin it X spaces, what space do you land on? For example, if the wheel has 9 spaces and you spin it 47 spaces (starting from 0), where do you land? That's the remainder or modulo, X%N. (47%9 = 2)

It's equivalent because what remains of 47 spaces after you've taken away all the full revolutions of the wheel that put you back where you started (multiples of 9, with the largest multiple being 5*9=45) is 2.
Title: Re: animating mutliple things at the same time
Post by: daniel on Fri 19/05/2017 09:16:55
hey guys,

so i just put in the code and thought i'd report back with the results.

it works fine but for some reason only in "repeatedly_execute_always()"...? when i put it in "room_RepExec()" nothing happened.
i also had to adjust the timer setting. it seems there's some weirdness going on with the tweenImage timing...when it's set to 0.5 it actually takes a second to complete the tween.
maybe the timing is on a "per image" basis? which doesn't really make sense since both images tween at the same time...oh well:D

anyway here's what i'm using now and it looks nice

unction repeatedly_execute_always()

  if (IsTimerExpired(GlitterTimer)){
    glitterFrame = (glitterFrame + 1) % 4;
    oGlitter.TweenImage(oGlitterEmpty, 0.25, 376 + glitterFrame, eEaseLinearTween, eNoBlockTween);
    SetTimer(GlitterTimer, GetGameSpeed()/2);
  }
  if (IsTimerExpired(SmokeTimer)){
    smokeFrame = (smokeFrame + 1) % 7;
    oChimneySmoke.TweenImage(oSmokeEmpty, 0.5, 382 + smokeFrame, eEaseLinearTween, eNoBlockTween);
    SetTimer(SmokeTimer, GetGameSpeed());
  }
}


thanks again for your help!
Title: Re: animating mutliple things at the same time
Post by: Khris on Fri 19/05/2017 14:23:50
When you tried putting it in room_RepExec(), did you add that function manually to the room script? Or did you create/link the function to the room event in the editor? Because if you didn't, room_RepExec simply won't get called by AGS.
Title: Re: animating mutliple things at the same time
Post by: daniel on Fri 19/05/2017 20:06:32
hm, yes "room_RepExec()" is linked through the editor. everything seems to be fine.
does it matter where in the script file the "room_RepExec()" is located?
because right now it's at the very bottom...