RogerMore Posted October 10, 2015 Share Posted October 10, 2015 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 More sharing options...
bruno_ Posted October 10, 2015 Share Posted October 10, 2015 try adding the animation to the sprite instead of the group.You can use foreach method of the group that passes the sprite to a function. Link to comment Share on other sites More sharing options...
jmp909 Posted October 10, 2015 Share Posted October 10, 2015 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 egvar 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 egvar 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 More sharing options...
MichaelD Posted October 11, 2015 Share Posted October 11, 2015 Also if you want to check the current animation only: .animations.currentAnim.onComplete.add(function () {}); Link to comment Share on other sites More sharing options...
RogerMore Posted October 12, 2015 Author Share Posted October 12, 2015 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 More sharing options...
jmp909 Posted October 12, 2015 Share Posted October 12, 2015 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 argumentshttp://phaser.io/docs/2.4.3/Phaser.Signal.htmladd(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 functionfunction stopMole(someMole) // <== someMole will be myou can call it what you want though .. this is fine still...startMole = function(m) { Link to comment Share on other sites More sharing options...
Recommended Posts