MarvinB Posted October 10, 2015 Share Posted October 10, 2015 Hey Guys, I am trying to implement a simple countdown to my game. Unfortunately, Phaser is throwing the following error: Uncaught TypeError: Cannot read property 'apply' of undefined The error occurs in this line in Phaser: this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args); The loop function calls my method once, so it counts down once and then throws the error. I am assuming the callback is not called correctly and therefore the event[this_i].callback is undefined. This is my code: ....... MMM.thisCountDown[id] = countdown; MMM.timerText[id] = this.game.add.text(0, 0, countdown, style); MMM.timerText[id].anchor.set(0.5); MMM.timerText[id].x = Math.floor(textbox.x+2); MMM.timerText[id].y = Math.floor(textbox.y+2); MMM.timerEvent[id] = this.game.time.events.loop(Phaser.Timer.SECOND, this.updateTimer(id)); MMM.backgroundobjects.add(textbox); } updateTimer(id) { MMM.thisCountDown[id] -= 1000; if(MMM.thisCountDown[id] === 0) { //to remove loop event this.game.time.events.remove(timerEvent[id]); MMM.timerText[id].setText("EXP"); } else { MMM.timerText[id].setText(MMM.thisCountDown[id]); } } Link to comment Share on other sites More sharing options...
jmp909 Posted October 10, 2015 Share Posted October 10, 2015 When you write..., this.updateTimer(id) );It calls the function immediately due to the (), and takes the result. It doesn't call it when the timer finishes like you are thinking ie try thisMMM.timerEvent[id] = this.game.time.events.loop(Phaser.Timer.SECOND, this.updateTimer(id));console.log("hello");updateTimer(id) { console.log("update")}your output will be updatehelloabd since updateTimer has no return value, you'd more or less be writing the equivalent ofMMM.timerEvent[id] = this.game.time.events.loop(Phaser.Timer.SECOND, null);updateTimer(id);Either create an inline anonymous function or pass the args another way. Some functions let you pass them after the scope parameter. I'll need to get home first to check specifics of your example Link to comment Share on other sites More sharing options...
jmp909 Posted October 10, 2015 Share Posted October 10, 2015 If you look at the code docs for loop you can pass arguments after the callback contexthttps://github.com/photonstorm/phaser/blob/master/src/time/Timer.jsso try ...., this.updateTimer, this, id)If that doesn't work try..., this.updateTimer.bind(this), this, id)I'm not quite sure when the scope needs binding.. I think I had to do it with tweens, but possibly not with timers Link to comment Share on other sites More sharing options...
MarvinB Posted October 11, 2015 Author Share Posted October 11, 2015 Hi jmp909, thank you very much. Your second approach worked just as expected! The only thing that I am still missing is the even removal on 0. Do I have to unbind the update function first, before I remove my timerEvent now?.... MMM.timerEvent[id] = this.game.time.events.loop(Phaser.Timer.SECOND, this.updateTimer.bind(this), this, id); MMM.backgroundobjects.add(textbox); } updateTimer(id) { MMM.thisCountDown[id] -= 1000; if(MMM.thisCountDown[id] === 0) { //to remove loop event this.game.time.events.remove(MMM.timerEvent[id]); MMM.timerText[id].setText("EXP"); } else { MMM.timerText[id].setText(MMM.thisCountDown[id]); } } Link to comment Share on other sites More sharing options...
MarvinB Posted October 11, 2015 Author Share Posted October 11, 2015 It goes into the if statement and sets EXP, but then continues into -1000... Link to comment Share on other sites More sharing options...
jmp909 Posted October 11, 2015 Share Posted October 11, 2015 I'm wondering if "this" now points to the wrong thing? Have you checked this.game is what it's suppose to be here? No errors?bind() just defines what the 'this' in the callback function will refer tohttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bindSo it should be ok... It must be a different issueIs it possible you created 2 events with the same id? In which case you'd be losing the reference to the first one when you set the second Link to comment Share on other sites More sharing options...
MarvinB Posted October 11, 2015 Author Share Posted October 11, 2015 I figured it out. 'This' was pointing to the right thing. The issue was that since I was calling my timer setup inside a function that has been called by an inputondown function, which for some reason triggers twice, my timer setup has also been triggered twice.This second call messed up the time event Link to comment Share on other sites More sharing options...
MarvinB Posted October 11, 2015 Author Share Posted October 11, 2015 I figured it out. 'This' was pointing to the right thing. The issue was that since I was calling my timer setup inside a function that has been called by an inputondown function, which for some reason triggers twice, my timer setup has also been triggered twice.This second call messed up the time event Link to comment Share on other sites More sharing options...
Recommended Posts