tzachshabtay / MonoAGS

AGS (Adventure Game Studio) reimagined in Mono
https://tzachshabtay.github.io/MonoAGS/
Artistic License 2.0
27 stars 8 forks source link

Tweens: self-rewind and completion callback #168

Closed ghost closed 6 years ago

ghost commented 6 years ago
  1. Tweens can be rewinded by calling Tween.Stop(TweenCompletion.Rewind). Is it possible to add a self-rewinding behavior to the tween, so that it stopped itself with Rewind?

  2. I now know it is possible to wait for tween using "await tween.Task"; but may there be a sense to have a callback that is run at completion?

tzachshabtay commented 6 years ago

I now know it is possible to wait for tween using "await tween.Task"; but may there be a sense to have a callback that is run at completion?

You can do that with tween.Task.ContinueWith(...). (on a side note- The Task API is awesome!)

Tweens can be rewinded by calling Tween.Stop(TweenCompletion.Rewind). Is it possible to add a self-rewinding behavior to the tween, so that it stopped itself with Rewind?

So is tween.Task.ContinueWith(() => tween.Stop(TweenCompletion.Rewind)) what you had in mind?

ghost commented 6 years ago

So is tween.Task.ContinueWith(() => tween.Stop(TweenCompletion.Rewind)) what you had in mind?

Could be, but I thought it may be convenient if there is simply a property in Tween that does that, especially since TweenCompletion.Rewind is already a feature of Tween.

tzachshabtay commented 6 years ago

tween.RewindOnCompletion(); Like this?

ghost commented 6 years ago

After posting last time, I thought one could write an extension method to Tween, which does "this.Task.ContinueWith(() => this.Stop(TweenCompletion.Rewind)". Is this what you mean?

It's just that I keep getting bothered by this: the engine seems to have a lot of capabilities, but coding game for it is very "hardcore" compared to original AGS scripting. I know you mentioned that you plan to make interaction editor, but many people will probably prefer coding their games. So I was thinking it could benefit from "helper" layer, which simplifies common manipulations with objects.

ghost commented 6 years ago

Oh, I just realized that I understood the meaning of tween's rewinding wrongly, and possibly explained what I was trying to do wrongly too.

What I meant, is repeating tween, that loops forever. That is - rewinds and restarts.

tzachshabtay commented 6 years ago

What I meant, is repeating tween, that loops forever. That is - rewinds and restarts.

Ah, got it, sure, I'll add it. This could be achieved, btw, like this:


private async void animate(IObject obj)
{
       var tween = obj.TweenSomething(...);
       await tween.Task;
       tween.Stop(TweenCompletion.Rewind);
       animate(obj);
}

the engine seems to have a lot of capabilities, but coding game for it is very "hardcore" compared to original AGS scripting.

Can you give examples of when AGS scripting is simpler? Or rather, everything you can think of?

ghost commented 6 years ago

Hey, I've actually figured how to write this with extension methods:

    public static class TweenExt
    {
        public static void RepeatForever(this Tween t)
        {
            t.Task.ContinueWith(a => {
                t.Stop(TweenCompletion.Rewind);
                Tween.Run(t.From, t.To, t.Setter, t.DurationInTicks / (float)AGSGame.UPDATE_RATE, t.Easing).RepeatForever(); }
            );
        }

        public static void RepeatTimes(this Tween t, int times)
        {
            if (times <= 0)
                return;
            t.Task.ContinueWith(a => {
                t.Stop(TweenCompletion.Rewind);
                Tween.Run(t.From, t.To, t.Setter, t.DurationInTicks / (float)AGSGame.UPDATE_RATE, t.Easing).RepeatTimes(--times);
            }
            );
        }
    }

Real example of use:

_roadBar.TweenX(-1280 % (_roadBar.Image.Width * 2), 1f).RepeatForever();
_dummyObj.TweenX(1000, 1f).RepeatTimes(3);

Not sure how optimal this is, but it works.

The only problem I found is that Tween does not keep duration in original form (seconds), so I have to convert it back from ticks when I restart the tween.

tzachshabtay commented 6 years ago

Glad you solved it. One thing that's probably not going to work with this approach is stopping a running tween, because it works against the first task and not against the continuation. I'll work on a built in solution.