Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: vga256 on Mon 14/03/2022 20:32:57

Title: Adding a StartAtFrame parameter to Button.Animate
Post by: vga256 on Mon 14/03/2022 20:32:57
As the title suggests - I'm looking for a recommended workaround that would allow me to choose the starting frame for a Button animation. The start frame option was added to Object and Character a few years ago, but Button fell by the wayside.

Because there is no function overloading allowed, what I'm asking for in the topic isn't possible in AGS. It seems that rewriting the entire Animate function, and replicating (in a new module) what Button.Animate does may be necessary. Can someone recommend a workaround that falls short of rewriting the entire Button.Animate implementation?
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: Cassiebsg on Mon 14/03/2022 20:46:14
The "obvious" workaround to me seems to be to manually animate the button.
Set the start frame as default, then change the button sprite to the next one with a while/for condition on a timer.
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: eri0o on Mon 14/03/2022 21:37:56
Just for kicks...

animate_btn.ash
Spoiler
Code (ags) Select
// new module header

import void AnimateEx(this Button*, int view, int loop = 0, int delay = 1, RepeatStyle style = eOnce, int frame = 0);

import void Stop(this Button*);
[close]


animate_btn.asc
Spoiler
Code (ags) Select
// new module script
#define MAX_ANIM_BTNS 32
#define ITERATE_BTNS for(int i=0; i<_btn_count; i++)

struct animated_ex_btn {
  int Frame;
  int Loop;
  int View;
  int Delay;
  int Ticks;
  RepeatStyle RepeatStyle;
  Button* Button;
};

int _btn_count;
animated_ex_btn _btn[MAX_ANIM_BTNS];

void _remove_btn(Button* btn)
{
  int k = MAX_ANIM_BTNS + 1;
 
  ITERATE_BTNS
  {
    if(_btn[i].Button == btn)
    {
      k = i;
    }
   
    if(i > k)
    {
      _btn[i-1].Frame = _btn[i].Frame;
      _btn[i-1].Loop = _btn[i].Loop;
      _btn[i-1].View = _btn[i].View;
      _btn[i-1].Delay = _btn[i].Delay;
      _btn[i-1].Ticks = _btn[i].Ticks;
      _btn[i-1].RepeatStyle = _btn[i].RepeatStyle;
      _btn[i-1].Button = _btn[i].Button;
    }
  }
 
  if(k <= MAX_ANIM_BTNS) {
    _btn_count--;
  }
}

void _add_btn(Button* btn, int view, int loop, int delay, RepeatStyle style, int frame)
{
  _btn[_btn_count].Frame = frame;
  _btn[_btn_count].Loop = loop;
  _btn[_btn_count].View = view;
  _btn[_btn_count].Delay = delay;
  _btn[_btn_count].RepeatStyle = style;
  _btn[_btn_count].Button = btn;
  _btn[_btn_count].Ticks = 0;
 
  _btn_count++;
}

void repeatedly_execute_always()
{
  ITERATE_BTNS
  {
    _btn[i].Ticks++;
   
    if(_btn[i].Ticks < _btn[i].Delay) continue;
   
    int loop = _btn[i].Loop;
    int view = _btn[i].View;
   
    int loop_count = Game.GetLoopCountForView(view);
    if(loop >= loop_count) continue;
       
    int frame_count = Game.GetFrameCountForLoop(view, loop);
   
    _btn[i].Ticks = 0;
    _btn[i].Frame++;
    if(_btn[i].Frame >= frame_count) _btn[i].Frame = 0;
    int frame = _btn[i].Frame;
   
    ViewFrame* vf = Game.GetViewFrame(view, loop, frame);
    int sprite = vf.Graphic;
   
    _btn[i].Button.NormalGraphic = sprite;
  } 
}

// public interface

void AnimateEx(this Button*, int view, int loop, int delay, RepeatStyle style, int frame) {
  _add_btn(this, view, loop, delay, style, frame);
}

void Stop(this Button*) {
  _remove_btn(this);
}
[close]

Not sure how well it works, but hey! It was a shot!
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: vga256 on Mon 14/03/2022 21:44:30
Haha wow @eri0o! Looks like you wrote almost the exact same implementation as me, and you solved a few of my problems with Views along the way! I'll give this a shot and provide an update in a bit.
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: eri0o on Mon 14/03/2022 22:57:27
Hey, the code has no safeguards, like you can make it wrong if you animate something twice without stopping before, there's no easy way to read the current frame and things like that.

If you think this is somewhat useful I may properly put this in a module and try to add the safeguards. I was kinda trying to see how small I could code this and it wasn't as small as I thought but still reasonably compact. :P
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: eri0o on Mon 21/03/2022 01:21:55
There's a reasonable chance this will be featured in a beta release in a near future.
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: vga256 on Mon 21/03/2022 16:39:36
Excellent! I'm still in the process of rewriting it for my code styling. Will keep you posted.
Title: Re: Adding a StartAtFrame parameter to Button.Animate
Post by: Crimson Wizard on Sat 02/04/2022 03:20:01
For information, 3.6.0 Beta now includes extended Button.Animate that has "starting frame" among the new parameters.