Simple timer within a function is not working

Started by Fedx, Thu 05/01/2017 10:44:28

Previous topic - Next topic

Fedx

I'm running into trouble making a simple timer. It's an arcade sequence within the game, but it's really short so there's not much code. I want my character to be able to slide in the ground when I click on a button. I made the background move while the player is static so there's no need to move it. My code looks something like this:

Code: ags

// room script file

int SlideTimer = 0;

function room_AfterFadeIn() //Play the music
{
  aArcade.Play(eAudioPriorityHigh, eRepeat);
}

function oSlide_AnyClick() //Clicking on the Slide Button
{
  if (SlideTimer == 0)
  {
    oLooper.Graphic = 20; //Looper is the Character
    oDust.Visible = true; //Little dust effect as he is gliding
      while (SlideTimer < 50) {     
        SlideTimer ++;
      }
  }
}

function room_RepExec()
{
  if(SlideTimer == 50)
  {
    SlideTimer = 0;
    oLooper.Graphic = 16;
    oDust.Visible = false;
  }
}


The thing is that the sliding "animation" only lasts for a frame, even if I put bigger numbers. I think there must be something odd with the "While" function, but I can't understand what. Thanks!
- The gamer doesn't dies... he respawns -

CrashPL

If you want to have non-blocking time-based events, I suggest using SetTimer and IsTimerExpired, instead of a simple counter in a loop. ;)

Snarky

Quote from: Fedx on Thu 05/01/2017 10:44:28
I think there must be something odd with the "While" function, but I can't understand what.

The problem is that the script doesn't wait a turn every time it runs through the while loop (because you don't tell it to). It runs through the loop 50 times in a single game turn (which a computer can do in basically no time at all).

Usually the way to fix this is to add a "Wait(1);" line inside the loop, but that makes the game block, which you probably don't want. One fix, as CrashPL says, is to use timers; another is to just change the logic a little, using the fact that room_RepExec() runs once every game turn, so you can start the counter in oSlide_AnyClick(), and keep counting up in room_RepExec() until you reach the point where you want to stop:

Code: ags
// room script file

int SlideTimer = 0;

function room_AfterFadeIn() //Play the music
{
  aArcade.Play(eAudioPriorityHigh, eRepeat);
}

function oSlide_AnyClick() //Clicking on the Slide Button
{
  if (SlideTimer == 0)
  {
    oLooper.Graphic = 20; //Looper is the Character
    oDust.Visible = true; //Little dust effect as he is gliding
    SlideTimer=1; // This tells room_RepExec() to start counting up
  }
}

function room_RepExec()
{
  if(SlideTimer>0)
  {
    SlideTimer++;
    if(SlideTimer == 50)
    {
      SlideTimer = 0;
      oLooper.Graphic = 16;
      oDust.Visible = false;
    }
  }
}

Fedx

Dang it! I upgraded recently to 3.3 and I didn't know about that function, thanks a lot! And if I can't get that to work I'll try Snarky's solution. Again, thanks for the help!
- The gamer doesn't dies... he respawns -

SMF spam blocked by CleanTalk