Jump to content

Timer


MarvinB
 Share

Recommended Posts

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

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 this

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

updatehello

abd since updateTimer has no return value, you'd more or less be writing the equivalent of

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

If you look at the code docs for loop you can pass arguments after the callback context
https://github.com/photonstorm/phaser/blob/master/src/time/Timer.js

so 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

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

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 to

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

So it should be ok... It must be a different issue

Is 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

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

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

 Share

  • Recently Browsing   0 members

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