wolf

Remove existing tweens on sprite

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?

Share this post


Link to post
Share on other sites

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!
 

Share this post


Link to post
Share on other sites

Here's a simple little routine which will plug right into Phaser's TweenManager and provide this functionality: http://jsfiddle.net/lewster32/L3u3gp5k/

 

Edit: Added this as a pull request: https://github.com/photonstorm/phaser/pull/1279

Edited by lewster32
Added details of PR

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
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).

Share this post


Link to post
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?

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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). 

Share this post


Link to post
Share on other sites
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();

 

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

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. 

Share this post


Link to post
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.

Share this post


Link to post
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. 

Share this post


Link to post
Share on other sites

I think if the tween itself is repeating, it is

tween.repeatCounter === -1

and if the current tween component (TweenData) is repeating,

tween.timeline[tween.current].repeatCounter === -1

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.