Jump to content

Animations and onComplete


RogerMore
 Share

Recommended Posts

Hi Guys,

 

After several experiments I decided to use Phaser for my framework to build me my first html5 game. When piecing my game together I have some troubles using animations.

 

My game is a molehunt clone. My create function creates a group which has 9 molehill sprites. Each sprites has the same animations from an empty molehill to a mole who's waiting for the action.

 

In my update function I have some code which determens if a new mole has to pop out and where. What I want to achieve is that a mole is chosen to begin, it will get a delay before the animation of the popping out starts, en when that animation is ready it gets a new delay before the going away animation is started. 

Because I wanted to take one step at a time I wanted to try out te concept without the delays, but for some reason I can't set the onComplete of the animation to my startMole function. I get the following error:

Uncaught TypeError: Cannot read property 'add' of undefined

 

Here's pieces of my code:

 



   
    buildMoles: function() {
    console.log('buildMoles');
        this.molegroup = this.add.group();
        this.molegroup.enableBody = true;

        for(var i=0; i<this.totalMoles; i++) {
            var m = this.molegroup.create(900, 200, 'mole');
            m.anchor.setTo(0.5, 1);
            m.body.moves = false;
            anim = m.animations.add('molehill', [0]);
            m.animations.add('mole_peek_out', [0,1,2,3,4]);
            m.animations.add('mole_peek_in', [4,3,2,1,0]);
            m.animations.add('mole_go_out', [0,1,2,3,4,5,6,7]);
            m.animations.add('mole_go_in', [7,6,5,4,3,2,1,0]);
            m.animations.play('molehill', 24, false);
            // console.log(m);
        }
this.prepareLevel();
    },
   
    startBunny: function(m) {
        m.animations.stop('molehill');
m.onComplete.add(this.stopBunny, this);
        m.animations.play('mole_go_out', 24, false);
    },


update: function() {
    // ...
    if (this.freeMoles > 0) {
    var whichMole = this.rnd.integerInRange(0, this.maxMoles-1);
    if (this.molesInPlay[whichMole] == 0) {
    this.molesInPlay[whichMole] = 1;
    m = this.molegroup.children[whichMole];
    this.startMole(m);
    this.freeMoles--;
    console.log(this.molesInPlay);
    console.log(this.freeMoles);
    }
    }
// ...
},


I'm sure I'm going about this the wrong way, but for now I don't have a clue what to try next.

 

Maybe there's someone who can help me?

 

Thanks in advance!

 

Roger

Link to comment
Share on other sites

you dont actually show the functions  in your code that you're trying to call (startMole)

 

I would check it's not a scope issue. also onComplete is not a method of a sprite, it's  a method of an animation eg

var anim = m.animations.add('molehill', [0]);anim.onComplete.add(this.animComplete, this)

also I know sometimes you need to bind your scope, although I think that's for tweens eg

var myTween = this.game.add.tween(this.mole).from({x:800+this.mole.width, y:600+this.mole.height}, 250, Phaser.Easing.Bounce.Out, true, 3000) myTween.onStart.add(this.moleTweenComplete.bind(this),this)

(note my code is TypeScript version)

 

 

try this maybe for a start... 

startBunny: function(m) {        m.animations.stop('molehill');               var anim = m.animations.play('mole_go_out', 24, false);       anim.onComplete.add(this.stopBunny, this);},
Link to comment
Share on other sites

Thanks guys for your quick replies.

 

@bruno: In the foreach method not displayed here I create a couple of sprites which get their own animations.

 

@jmp909: You are so right about the function startMole. When copying snippets out of my code I must have copied the wrong function name. The name should be startMole instead of startBunny.

 

@MichaelD: thanks for the tip.

 

I ended up with the following code:

 

finishMole: function(m) {console.log('finishMole');var whichMole = m.whichMole;this.molesInPlay[whichMole] = 0;this.freeMoles++;console.log(this.molesInPlay);console.log(this.freeMoles);console.log('finishMole end');},          stopMole: function(m) {    console.log('stopMole');    console.log(m);       anim = m.animations.play('mole_go_in', 24, false);       anim.onComplete.add(this.finishMole, m);    console.log('stopMole end');   },       startMole: function(m) {    console.log('startMole');    console.log(m);       anim = m.animations.play('mole_go_out', 24, false);       anim.onComplete.add(this.stopMole, m);    console.log('startMole end');   },

The startMole function will start the beginning animation of the sprite and calls function stopMole. This works, the mole pops out, stopMole is started. But as soon als I try the same anim.onComplete.add(this.finishMole, m); code again so that when the animation of the mole going away is finished, the function finishMole should be called, I get the following error:

Uncaught Error: listener is a required param of add() and should be a Function.

 

I don’t see the difference between startMole en stopMole en why anim = m.animations.play has to go wrong...

 

Anyone any sugestions?

 

Thanks in advance,

 

Roger

 

Link to comment
Share on other sites

console.log(this) and check it points to the correct thing

 

you've probably lost your scope

 

in fact you're passing m as the listenerContext (you assumed it was the first argument to the function which it isn't.. see definition below), meaning this in your callback function now points to m, not game (or whatever the original 'this' context was). that's wrong since you're essentially then trying to call m.stopMole but stopMole is not a method of m!

 

http://phaser.io/docs/2.3.0/Phaser.Signal.html#add

 

actually those are old docs, Phaser 2.4.x will let you pass args as well as the final arguments

http://phaser.io/docs/2.4.3/Phaser.Signal.html

add(listener, listenerContext, priority, args) 

you don't need to pass (m) anyway.. it's already the first argument to your callback function

 

For example: Phaser.Key.onDown when dispatched will send the Phaser.Key object that caused the signal as the first parameter

 

 

 

so...

anim = m.animations.play('mole_go_in', 24, false);anim.onComplete.add(this.stopMole);

passes m as the first parameter into the callback function

function stopMole(someMole)  // <== someMole will be m

you can call it what you want though .. this is fine still...

startMole = function(m) {
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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