Tween.finished called if tween is stopped?

Not favoritedFavorited Favorited 0 favourites
  • 7 posts
From the Asset Store
Calculate parabolic trajectories and tween objects over them.
  • I hope Ashley can chime in here I don't wanna put it as a bugreport because it could be by design.

    In Events:

    If I start a tween (2seconds) that I then stop after 1 seconds. The tween just stops.

    On Tween "Tag" finished does NOT trigger.

    In Script:

    class MySprite extends ISpriteInstance {
    	constructor() {
    		super();
    	}
    
    	async start() {
    		this.tween = this.behaviors.Tween.startTween("x", this.x+200, 2, "linear");
    		this.tween.finished.then(() => {
    			this.setAnimation("Animation 2")
    		})
    	}
    
    	cancel() {
    		if(this.tween.stop) this.tween.stop();
    	}
    }

    I do essentially the same. However, this.tween.finished.then() still runs anyway (right when the tween is stopped). My thinking was that if the Tween is stopped, I would not consider it finished. It's stopped.

    I guess the solution would be to track an extra variable that shows that the tween was stopped and not simply finished. It would be much more convenient though if at least I could get "was the tween stopped" from the ITweenState somehow, however, ITweenState becomes effectively unusable after stop.

    So is this by design, a bug, a feature?

  • When you stop a tween it is completed. To do what you where thinking about you should use pause and then use resume to restart from the place it was left in.

  • I think the issue is that it's inconsistent between events and scripting. Which is confusing.

    The word finished does make it sound like it ran until the end to me. And this is how the condition "on tween finished" works. When you stop a tween the event condition on tween finished does NOT run.

  • Ah pause... duh. Yeah that appears to work SORT OF with some adjustments.

    There's just one thing that worries me though... I do in fact want the tween to end there, no need to resume. If I pause it, isn't it just floating around in memory indefinitely? And the async call is also kept waiting for the tween to end?

    Some context, I'm using it for an attack animation. Here's how it looks in short

    async attack() {
    	if(this.attacking) return;
    	this.attacking = tween;
    	tween.finished.then(
    		//do whatever
    	)
    }
    
    cancelAttack() {
    	this.attacking.pause();
    	this.attacking = null;
    }

    If I cancel the attack during it's animation and just pause the tween... I can literally never actually stop the tween because as soon as I do that, the async will resume its tween.finished.then() which I don't want. Something doesn't add up, perhaps a skill issue on my part?

  • I see, I am looking at it right now and there is a difference when a tween is stopped from an event and when it is stopped from the scripting API. Probably the scripting API needs to change to do the same as the events.

  • WackyToaster Yeah if you do that, the reference to the tween will be kept around because technically it is never finished.

    Right now I would keep track myself of what is going on and then do different things when the tween says it is finished.

    Use a variable to keep track of when you stopped the tween. When the finished promise is resolved, check if you stopped it and do what you need to do and if you didn't stop it you can let it do something else.

    async attack()
    {
    	if(this.attacking)
    		return;
    	
    	this.attacking = tween;
    	tween.finished.then(
    		
    		if (this.attacking)
    		{
    			// do something when finished with no interruption
    		}
    		else
    		{
    			// do something when cancelled
    		}
    	)
    }
    
    cancelAttack()
    {
    	this.attacking.stop();
    	this.attacking = null;
    }
    
  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Pretty sure your code does not work unless I mucked it up.

    this.tween.finished will run before this.attacking = null. So the following check for if(this.attacking) will always be true.

    But I do get the gist, I just need an extra variable to track.

    I don't wanna implement it though if you plan on changing how this works anyway. :^) So if you plan on changing it I will post it to the tracker for tracking purposes. I'm really not acutely worried about a memory leak that happens if I spend an hour attacking.

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)