anthkris

Timer onComplete callback not working

Recommended Posts

Howdy all,

I'm using a bit of script (http://blogs.bytecode.com.au/glen/2015/12/30/letter-by-letter-text-effect.html) for a dialog box in prefab. The actual text is displaying as expected. The main function is firing. However, the onComplete callback inside of displayLetterbyLetter does not ever fire. I'm not sure what I'm doing wrong. I've used this in another game and it worked perfectly. Any help? (The commented code is part of the callback fed into displayLetterbyLetter text which I pasted in to see if the function was doing something else weird. But the commented script works perfectly. It's just that the callback never ever fires).

var Paleo = Paleo || {};

Paleo.Thorg = function(game, message){
    Phaser.Sprite.call(this, game);
    //this.game = game;
    this.message = message;
    
    this.textObject = this.game.add.bitmapText(90, this.game.world.height - 80, 'jaynk', this.message, 22);
    this.textObject.visible = false;
    
    this.displayLetterByLetterText(this.textObject, this.message, function(){
        // stuff you want to do at the end of the animation
        this.game.time.events.add(Phaser.Timer.SECOND * 3, function(){
        	this.textObject.destroy();
        }, this);
        console.log("text end");
    }, this);
};

Paleo.Thorg.prototype = Object.create(Phaser.Sprite.prototype);
Paleo.Thorg.prototype.constructor = Paleo.Thorg;
Paleo.Thorg.prototype.displayNextLetter = function(){
		this.textObject.visible = true;
        this.textObject.text = this.message.substr(0, this.counter);
        this.counter += 1;
};

Paleo.Thorg.prototype.displayLetterByLetterText = function (textObject, message, onCompleteCallback) {
    var timerEvent = this.game.time.events.repeat(80, message.length, this.displayNextLetter, 
                                { textObject: textObject, message: message, counter: 1 });
    console.log(timerEvent.timer.onComplete);
    timerEvent.timer.onComplete.addOnce(onCompleteCallback, this);
    // this.game.time.events.add(Phaser.Timer.SECOND * 12, function(){
    //     this.textObject.destroy();
    // }, this);
};

 

Share this post


Link to post
Share on other sites

OK not sure I can help, I use createjs. 

Though here is a successful timer in that framework;

First createjs uses RAF (request animation frame);


createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;

	function createCountDown(timeRemaining) {
    var startTime = Date.now();
    return function() {
       return timeRemaining - ( Date.now() - startTime );
    }
} 

Timer text, so we can watch the countdown.

var timerText = new createjs.Text("Time Remaining: ", "30px Acme","#8e2f2f");
	timerText.x = 20;
	timerText.y = 480;
	level1.addChild(timerText);

Let's set the countdown time

var currentCountDown = createCountDown(49000);////////////////////////COUNT DOWN

Now we watch it work

level1.on("tick", function(event) {
	var countDownValue = currentCountDown();
            timerText.text = "Time Remaining: " + countDownValue;
			 if (countDownValue <= 0){
                splashText.text = "Your score was: "+ hitCount;
				 stage.removeChild(level1);
				 stage.addChild(splash);
				createjs.Tween.get(splash)
				.to({y: 50}, 400);}else if(bulletCount <= 0){
                splashText.text = "Your score was: "+ hitCount;
				 stage.removeChild(level1);
				 stage.addChild(splash);
				createjs.Tween.get(splash)
				.to({y: 50}, 400);}
});

There is some other things going on there in the last snippet like 'bulletCount' and 'hitCount'.

You might want to use a math.round, to get it showing in seconds or minutes or however you want it displayed.

Aside from it being based on a framework that's just a minimal part of some decent raw code for a timer.

Hope that's useful. You can see it work here; http://harrywatson.altervista.org/Happyapp/happy.html

Share this post


Link to post
Share on other sites

Thanks, @harrywatson As far as I can see the timer is set up correctly by Phaser standards. I am noticing that, whereas in the other game where I use the code snippet, the timer seems to be only generating one event, in this game, it's generating 3 or 4 which may be the reason why onComplete never fires. But I can't see what's causing this difference. 

Share this post


Link to post
Share on other sites

I figured out the problem! The game generates random food sprites for collection so I have several loops running. That means that the timer created in the prefab isn't the only timer, as it seems to assume(?), which is why onComplete never fires. Anywhoodle, if I remove the other loops, then it works as expected. So now I have to figure out how to have the loops and this timer simultaneously.

Share this post


Link to post
Share on other sites

Still looking for help on this if anyone has any to give. So far, nothing I've tried has been able to stop this specific timer. I don't know what to do. The only thing that seemed to work was to create the timer in the GameState using create and then using add in the prefab. Then at least the timer completed but, of course, it only fired once. 

Share this post


Link to post
Share on other sites

Ahh! You need maybe some 'if' and 'else' statements going on in there.

sorry in advance for the not code

var continue=true;
var pause=false;
function stopMe (pause continue){ 
if continue==true(
//your date and timer functions here
)}else if{ continue==false
//your date and time functions here
if (whatYouWant <= 10 timer=stop){ eradicateNastyOne } else if {whatYouWant <= 20 timer=continue} eradicateNastyTwo

and so on. Also you could say ; if nastyOne is eradicated your timer = +whatever value

Also just a quick word on debugging; You could take out each 'this' statement. one by one

and then re run the application.

and then re instate each 'this' statement

and then re run the application.

If there is one statement 'this' or any other that doesn't effect the application, comment it out.

So: One 'this' delete - re run - re instate. Second 'this' delete - re run - re instate, and so on.....

I know it's a pain in the proverbial but it's the fastest learning curve I've found.

Have you looked at a plain javascript solution?

 

Good Luck

 

 

 

Share this post


Link to post
Share on other sites

Howdy @harrywatson I tried to implement setTimeout with mild success, but it just struck me as "wrong." It seems like I should be able to do this with the appropriate Phaser constructs (though that may just be me being stubborn and "working the problem"). When I remove the three other loops, then the prefab and timer work as expected. With the other loops in, even when I move them around to start after the prefab repeat timer, then the prefab timer never sends the complete signal. I also scoured the docs and was able to force-send the dispatch signal for onComplete for that particular timer, which may be my best hope.... But I can't understand why I can't have all four timers working in harmony and it's bothering the stuffing out of me!

Share this post


Link to post
Share on other sites

Finally fixed it! It isn't perfect but at least it uses Phaser methods. Like so:

Paleo.Thorg.prototype.displayNextLetter = function(textObject, message, counter) {
	this.textObject.visible = true;
	this.textObject.text = this.message.substr(0, this.counter);
    this.counter += 1;
    if (this.counter > this.message.length){
        Paleo.Thorg.timerEvent.timer.onComplete.dispatch();
    }
};

Paleo.Thorg.prototype.displayLetterByLetterText = function (textObject, message, onCompleteCallback) {
    Paleo.Thorg.timerEvent = this.game.time.events.repeat(100, message.length, this.displayNextLetter, 
                                {textObject: textObject, message: message, counter: 1});
    Paleo.Thorg.timerEvent.timer.onComplete.addOnce(onCompleteCallback, this, 10);
};

Thanks a bunch for your help @harrywatson!

Share this post


Link to post
Share on other sites

Hey great, well done! Code is fantastic fun. Like a crossword on steroids.

Yes you're right setTimeout and some others are wrong for games.

Though don't shy off raw code altogether. It's where you might do your most

original work. I've made a door opener and closer and a combination lock code for

click and point or escape type games. The combination lock one took about three weeks.

Plus I adapted a shoot 'em code which was raw javascript. Now it's unrecognisable

from the original and I now see it as my own.

 

Great adventures!

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.