GML [SOLVED] Timer inside bigger timer wont go down? HELP!

K

Kaijyuu

Guest
hello, good day everyone.

Im having trouble making an object (hot vapor spilling out of an old pite (hurts the player)) to trigger at different times using the same object, I tried coding it like this set a total_time make it reach 0 when that happens my program choses 3 cases (0,1,2) depending on this case timer is set to 30,60 or 80.

now everything works fine until I try to make the timer to go down to 0, no matter what I do it stays in 29,59 or 79 its only substracting 1 but its not looping for it to get to 0 and thus trigerring the hurtin animation of my vapor!

cant get it to loop correctly!

ill post my noob code next:
Code:
image_speed = 0;
if(total_time > 0)
{
   total_time = total_time - 1;
   if (total_time = 0)
   {
       time = choose (0,1,2)
       switch(time)
       {
           case 0:
           timer = 30;           
           if (timer > 0)
           {
               timer = timer - 1;
               if (timer = 0)
               {
                   sprite_index = spr_vapor;
                   image_speed = 1;
                   if (floor(image_index) == 56)
                   {
                       total_time = 300;
                   }
               }
           }
           break;
           case 1:
           timer = 60;
           if (timer > 0)
           {
               timer = timer - 1;
               if (timer = 0)
               {
                   sprite_index = spr_vapor;
                   image_speed = 1;
                   if (floor(image_index) == 56)
                   {
                       total_time = 300;
                   }
               }
           }
           break;
           case 2:
           timer = 80;
           if (timer > 0)
           {
               timer = timer - 1;
               if (timer = 0)
               {
                   sprite_index = spr_vapor;
                   image_speed = 1;
                   if (floor(image_index) == 56)
                   {
                       total_time = 300;
                   }
               }
           }
           break;
           break;
       }
   }
}
aditional info: total_timer is set to 300 (that is working fine!)
timer is set in the create event to (-1)
 

Attachments

NightFrost

Member
The switch will run only after total_time has reached zero, and only while total_time remains zero. I'm not sure what the intent of this timer is, as by your description you only want a 30/60/80 step counts. However, in the inner loop, on every step, you choose and choose again one of the three timers, set it to maximum value, and decrement by one. Because you are setting it every step back to maximum, it will obviously never reach zero and set the sprite variables or total_time back to non-zero value.

You should get rid of the outer counter, set timer to either 30/60/80 in Create event, have it count down and then set it again to one of those three values.
 
K

Kaijyuu

Guest
Yes but without the total_time gms2 sets every frame a new value into the same object so the same object keeps looping 29-59-79-29-59-79 and so on, so even if it is making - 1 every frame it is also changing the original value to another value, to stop that from happening I made the total_time timer, I want to randomize the time for each of the same objects to trigger so the don't trigger all at once.
 

NightFrost

Member
That's why you initially set timer in Create event, then let it count down, and once at zero choose again. If you want them totally randomized from the start, put irandom(80) as initial value. This means some of them go off almost immediately.
 
K

Kaijyuu

Guest
That's why you initially set timer in Create event, then let it count down, and once at zero choose again. If you want them totally randomized from the start, put irandom(80) as initial value. This means some of them go off almost immediately.

Ohhh I'll try this out later today and see if it works, looks like I made it harder for myself than I should have lol!
 
K

Kaijyuu

Guest
Hey @NightFrost I tried what you say and looks like its working but since is randomizing every frame, I never gets to 0 and never triggers the animation. Do you happen to know a way to store the value it ramdomly gives at the specific frame and equal that value to timer so it eventually does get to 0?

I tried storing the random value in a veriable called number and then equal that value to the timer but the timer still changes value at random rates! ill leave the code!
Code:
image_speed = 0;
number = irandom(80);
timer = number;
if(timer > 0)
{
   timer = timer - 1;
   if (timer < 0)
   {
       sprite_index = spr_vapor;
       image_speed = 1;
   }
}
Ill keep trying see if I can get it done, thanks for the help m8!
 

asollazzo

Member
Typing on my phone so not tested or formatted well
Code:
Image_speed=0;
If timer > 0
{
Timer -=1;
If timer <= 0
{
sprite_index = spr_vapor;
image_speed=1;
timer=irandom(80);
}
}
Stick timer=irandom(80) in the create event too
 

NightFrost

Member
Oh, I notice I wasn't paying attention. Of course two timers are needed. One to count down until vapor spills out, and another to count the length of the vapor spill effect. Lets make it a simple state machine with just two states (untested code).
Code:
// CREATE EVENT

enum Vapor_State {
    Idle,
    Release
}
State = Vapor_State.Idle;

image_speed = 1;
Idle_Time_Max = 300;
Idle_Time = irandom(Idle_Time_Max);
Vapor_Time = 0;

// STEP EVENT

// State: not releasing vapor.
if(State == Vapor_State.Idle){
    // Decrement timer until it hits zero, then switch to vapor release state.
    if(Idle_Time-- == 0){
        State = Vapor_State.Release;
        sprite_index = spr_vapor; // Set sprite.
        Vapor_Time = choose(30, 60, 80); // Randomly choose vapor release time of 30, 50 or 80 steps.
    }
}
else if(State == Vapor_State.Release){
    // Decrement timer until it hits zero, then switch to idle state.
    if(Vapor_Time-- == 0){
        State = Vapor_State.Idle;
        sprite_index = -1; // Remove sprite.
        Idle_Time = Idle_Time_Max;
    }
}
This arrangement always sets the idle time between vapor releases to 300 steps (except the first, so they don't fire in unison) but the length of vapor release is randomly 30/60/80 steps every time.
 
K

Kaijyuu

Guest
Thanks for the help!
The code works but its reseting the value before the animation can start I tried tweeking it a little bit, but now when it gets to 0 it stays as 0, doesnt move on to start the animation nor it resets the timer!
ill leave the code in case you want to try it out!
Code:
image_speed=0;
if (timer > 0)
{
   timer -=1;
   if (timer = 0)
   {
       sprite_index = spr_vapor;
       image_speed=1;
       if((sprite_index = spr_vapor and floor(image_index) == 56))
       {
           timer=irandom(80);
       }
   }
}
I also tried puting "and timer = 0" in the last "if" statement! but the same happens!
 
K

Kaijyuu

Guest
this worked! I didnt want to dwell into state machines becuase my main character has like 20 states already, but I see its the best way to handle almost anything.
Thanks!
 
Top