Jump to content

Remove existing tweens on sprite


wolf
 Share

Recommended Posts

Say I start a tween with game.add.tween(mySprite), but then halfway into the tween I change my mind and want to stop & remove all tweens involving the sprite. I'm hoping to find something along the lines of game.removeAllTweensFrom(mySprite). Is there something like that?

Link to comment
Share on other sites

  • 2 months later...

I have been trying to remove the tweens that were added in the states of my game but they do not get removed and cause the game to start chugging after a few plays. When the user replays the game, old tweens are still hanging around and are doubling each time a new game is played. I have tried every method on this forum but nothing is working.

I add several tweens during each state to animate in objects to the screen like so: playButtonTween = this.game.add.tween(playButton).to({x: 390, alpha:1}, 1500, Phaser.Easing.Quintic.Out, true, 0, false);

I have a function called shutdown (reserved function in Phaser) that I call before my game transitions from one state to another (i.e. Menu ==> Instructions). In this function I have tried to remove the tweens but when I console.log the this.tweens on shutdown, I am still seeing the tweens listed.

I am able to get all the tweens by calling game.tweens.getAll().I try to remove all the tweens in the state by calling game.tweens.removeAll(), but after console.logging this.tweens they are still there.

shutDown: function ()
{
        console.log("game.tweens getALL before: "+ game.tweens.getAll());

        game.tweens.removeAll();
        
        console.log("game.tweens getALL after: "+ game.tweens.getAll());
}

This is logged when I leave the Menu state the first time:
game.tweens getALL before: [object Object],[object Object],[object Object],[object Object]

game.tweens getALL after: [object Object],[object Object],[object Object],[object Object]

This is logged when I leave the Menu state the second time:

game.tweens getALL before: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

game.tweens getALL after: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

This is logged when I leave the Menu state the third time:

game.tweens getALL before: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

game.tweens getALL after: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

As you can see, the tween objects never get deleted and keep getting added.

I have tried other suggestions on this forum using methods from the previous builds of Phaser but none of them work either:
this.game.tweens.remove(tweenName);
this.tweens.remove(tweenName);

this.tweens.removeAll();

// destroy tween (this works to stop the tween and set it to null, but its still in the this.tweens list)
if (this.playButtonTween)
{
     this.playButtonTween.onComplete.removeAll();
     this.playButtonTween.stop();
     this.playButtonTween = null;
}

Rich suggested: “Keep a reference to the tweens you create and then game.tween.remove() them.” I do that and have no problem accessing the tween list. But game.tween.remove() does not work for me.

 

What should I do? This is slowing down and eventually killing my game play because nothing is getting cleared out.

 

Thanks!
 

Link to comment
Share on other sites

  • 5 months later...
  • 2 weeks later...

Just tracked down a problem in my code which my own version of a removeFrom function was failing,  lwesters solution suffers the same problem.

 

The problem is that is doesn't remove entries from tweenManagers _add list.  The _add list is a buffer that delays adding new tweens to the main _tweens until after the next update (must be a reason for it, but why?).

 

So if your code adds a new tween and then tries to remove it before going through an update cycle, it won't get removed.

 

I could access the _add list and cleanse that, but I'd rather not access an inner var and there seems to be enough support for this functionality so it should go in.  The question is, what to do with the _add list?

 

I'd say the _add list should be processed.

Link to comment
Share on other sites

The reason for the _add list is that if you don't buffer the creation of new tweens you are manipulating the _tweens array in real time, which causes the cached length to be wrong and the array slice (that removes dead tweens) from working if you create any tweens in callbacks off of the update loop (which loads of you do!). The add list is processed after the main tween list, so it captures tweens created in callbacks instantly with no frame delay.

 

tween.remove() will flag a tween for removal regardless which list its in (_tween or _add).

Link to comment
Share on other sites

Ah yes, that old chestnut, don't remove things from the list you are iterating through.

 

There's also a question that raises itself about getAll(), it doesn't return the entries in the _add list, so it doesn't really return them all, so should it?

Link to comment
Share on other sites

getAll needs recoding entirely to be honest - it returns a reference to the actual tweens array, so if you change it in any way (especially during a callback) you could really screw things up. It also includes tweens pending deletion, which it probably shouldn't do either.

Link to comment
Share on other sites

  • 8 months later...

You could add that kind of functionality yourself if you need it. Tweens are managed by a global tween manager and not by the things they are tweening, since you can tween nearly anything, whether it's aware of tweening or not. If you need a sprite to manage its own tweens, you can extend or modify the Phaser.Sprite class with a makeTween function that's a wrapper around this.game.add.tween, except it also keeps a local reference. If you do that, then you can keep sprite tween management local without affecting the tween manager's ability to tween on anything.

 

An alternative would be to walk the tween manager's tween list looking for mySprite as the target, but if you want to keep it correct you'd also need to check every single property of mySprite too, or make sure you always make tweens directly on sprites and not on any properties of a sprite.

 

It's generally easier to keep a reference than it is to dig one up at any given time.

Link to comment
Share on other sites

  • 7 months later...

The problem with creating your own reference is that you end up with messy code :). It'd be much nicer to have Phaser keep a reference to active tweens on any given object. For example, if one of my sprite is tweening, I want a current tween property just like I have a current anim property for animations. Perhaps this would mean re-structuring the tween manager like the animations manager (e.g. each sprite has its own manager). 

Link to comment
Share on other sites

  • 2 months later...
4 hours ago, fitness23 said:

Is there a way you can cancel / remove a specific tween on a specific sprite?

ie. sprite.cancelTween("walk");

You can store references something like this:

var sprite = game.add.sprite(0, 0, 'sprite-key');

sprite.tweens.tweenName = game.add.tween(sprite);

// later, you can use this reference in your app
// to stop tween
sprite.tweens.tweenName.stop();

 

Link to comment
Share on other sites

@scofield You've actually helped me fix another issue I had as well :) You've blown my mind! I never knew I could add a sprite or tween directly onto the character object in question. I've been dealing with separate variables all this time and having to marry everything up later. I thought this way because every example you see of say creating a sprite, the example always shows it's saved to a variable and so I thought that was the only way you can do things.

Link to comment
Share on other sites

1 hour ago, fitness23 said:

@scofield You've actually helped me fix another issue I had as well :) You've blown my mind! I never knew I could add a sprite or tween directly onto the character object in question. I've been dealing with separate variables all this time and having to marry everything up later. I thought this way because every example you see of say creating a sprite, the example always shows it's saved to a variable and so I thought that was the only way you can do things.

@fitness23 You welcome mate. I had the same problem with managing tweens before. About solution, It's just JavaScript :), you can create new object properties dynamically, it's nice from one side, but from another side you can easily override properties you created before, so they are not protected.

Link to comment
Share on other sites

  • 11 months later...

Suppose I want to pause all tweens or resume all infinite repeating tweens on a given sprite? Is there a non-messy way to do that (i.e. one that does not involve searching through every possible tween and checking the target)?

Perhaps there is some way to modify game.add.tween so it automatically pushes to an array (stored as a property on the sprite object). I understand it could get really messy if you are adding lots of tweens, but suppose you only want to store tweens that repeat infinitely? 

Of course, I can manually create the references, but my game has so many tweens added in different places, it would be a big effort. It would be much more ideal to modify game.add.tween so it automatically creates the references. 

Link to comment
Share on other sites

var tweenManagerAdd = Phaser.TweenManager.prototype.add.bind(Phaser.TweenManager);

Phaser.TweenManager.prototype.add = function (tween) {
  tweenManagerAdd(tween);
  (tween.target.tweens || (tween.target.tweens = [])).push(tween);
};

You would probably want to modify TweenManager.prototype.remove as well.

Link to comment
Share on other sites

2 minutes ago, samme said:

var tweenManagerAdd = Phaser.TweenManager.prototype.add.bind(Phaser.TweenManager);

Phaser.TweenManager.prototype.add = function (tween) {
  tweenManagerAdd(tween);
  (tween.target.tweens || (tween.target.tweens = [])).push(tween);
};

You would probably want to modify TweenManager.prototype.remove as well.

Nice. But is there an easy way to discriminate between infinite looping tweens (tweens set to repeat -1) and non-infinite? I would only want to create references to tweens that repeat forever. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...