Jump to content

time event this.events[this._i].callback.apply is not a function


Elvis
 Share

Recommended Posts

Hi,

I'm a Phaser beginner. 

I'm using IntelXDK + Phaser.io theme (version 2.6.1).

I'm trying to user a simple time event to stop an animation after 6 seconds.

I think it is because the notation

name: function () {}

provided by intelXDK model that I'm using but I'm not sure.

PS: If I use only the name of the function (instead of BasicGame.Game.prototype.happyMsgSystem), it doesn't work.

 

The code:

BasicGame = {
};

BasicGame.Game = function (game) {
};

BasicGame.Game.prototype = {

    preload: function () {
        this.load.spritesheet('button', 'asset/planet3.png', 59, 58,6); 
        this.load.spritesheet('robot', 'asset/robot/robot-sprite.png', 587, 587,5); 
    },

    create: function () {
        //this.button = this.game.add.button(this.game.world.centerX - 95, 400, 'button', BasicGame.Game.prototype.happyMsgSystem, this, 2, 1, 0);
        this.game.time.events.add(Phaser.Timer.SECOND * 6,1,BasicGame.Game.prototype.happyMsgSystem,this);

    },

    happyMsgSystem: function () {
        this.robot.animations.add('happyMsg', [1,2], 2, true);
        this.robot.play('happyMsg');
    },
};

Link to comment
Share on other sites

http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

I'm on my phone and can't copy stuff, but the problem is the line where you write this.game.add.button . In this scope 'this' is in fact 'game' , so you are essentially calling game.game.add.button . I recommend you read the link I provided and use the 'this' keyword less, until you get a better idea of phaser and JavaScript as it will make it hard for people to understand the scope of your variables.

Link to comment
Share on other sites

I agree w/ symof; I think you've got some scoping issues and also some Phaser usage issues.

Could you try something like this? Obviously you'll need to make some modifications to your own code, but it should get you in the right direction, I believe.

(function(){
  // I'm simply defining the variables you end up using below in one place.
  var game, robot, preload, create, happyMsgSystem;

  preload = function () {
    game.load.spritesheet('button', 'asset/planet3.png', 59, 58,6); 
    game.load.spritesheet('robot', 'asset/robot/robot-sprite.png', 587, 587,5); 
  };

  create = function () {
    // game.time.events.add(delay, callback, callbackContext, arguments)
    // I think you had the arguments to events.add() wrong, so I checked the docs and came up with this:
    var delay = Phaser.Timer.SECOND * 6;
    game.time.events.add(delay, happyMsgSystem, this);
    // TODO: create your robot and place in your game world.
  }

  happyMsgSystem = function () {
    robot.animations.add('happyMsg', [1,2], 2, true);
    robot.play('happyMsg');
  }

  game = new Phaser.Game(640, 480, Phaser.AUTO, '', { preload: preload, create: create });
})();

The way I've written it above, all of your variables will exist in the same scope, and you should not have to use "this" to access them.

Link to comment
Share on other sites

Thank you for the link.

Actually, the problem is in this line:

this.game.time.events.add(Phaser.Timer.SECOND * 6,1,BasicGame.Game.prototype.happyMsgSystem,this)

the button is commented  

If I try

this.game.time.events.add(Phaser.Timer.SECOND * 6,1, happyMsgSystem,this)

or 

this.game.time.events.add(Phaser.Timer.SECOND * 6,1, happyMsgSystem)

or 

game.time.events.add(Phaser.Timer.SECOND * 6,1, happyMsgSystem,this)

the error message persists

Thanks

Elvis
 

Link to comment
Share on other sites

As I said before it's the scope of your variables. The example I gave was just the first line of code that I saw.

1. You do not use 'this' keyword properly

2. You do not use the prototype properly

3. You declare variables outside of the scope that you are using them in.

BasicGame.Game.prototype = {

    preload: function () {
        this.load.spritesheet('button', 'asset/planet3.png', 59, 58,6); 
        this.load.spritesheet('robot', 'asset/robot/robot-sprite.png', 587, 587,5); 
    },

Here the preload function is part of the 'game' object and it get's called by phaser with game.preload

create: function () {
        //this.button = this.game.add.button(this.game.world.centerX - 95, 400, 'button', BasicGame.Game.prototype.happyMsgSystem, this, 2, 1, 0);
        this.game.time.events.add(Phaser.Timer.SECOND * 6,1,BasicGame.Game.prototype.happyMsgSystem,this);

    },

this button = game.game.add.button

game.game.time.events.add (xxxxxxxxxxxxx)

you calling them outside of the scope(which you understood). BUT! You are also using 

BasicGame.Game.prototype.happyMsgSystem

1. Your happyMsgSystem is a FUNCTION and you are calling it as an object.

happyMsgSystem: function () {
        this.robot.animations.add('happyMsg', [1,2], 2, true);
        this.robot.play('happyMsg');
    },

You should be calling it with happyMsgSystem();

 

2. You are calling it as a function inside the prototype when it should be inside the game object instead.

 BasicGame.Game.happyMsgSystem()

http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/

http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

 

Write your code without 'this', once it works then add it.

 

 

This is how your code should have looked;

BasicGame = {
};

BasicGame.Game = function (game) {
};

BasicGame.Game.prototype = {

    preload: function () {
        this.load.spritesheet('button', 'asset/planet3.png', 59, 58,6); 
        this.load.spritesheet('robot', 'asset/robot/robot-sprite.png', 587, 587,5); 
    },

    create: function () {
        //this.button = this.add.button(this.world.centerX - 95, 400, 'button', this.happyMsgSystem, this, 2, 1, 0);
        this.time.events.add(Phaser.Timer.SECOND * 6,1,this.happyMsgSystem(),this);

    },

    happyMsgSystem: function () {
        this.robot.animations.add('happyMsg', [1,2], 2, true);
        this.robot.play('happyMsg');
    },
};

 

You are also not declaring the 'robot' object anywhere, if that is all your code, or you are declaring it as a child of 'window' if it's outside the basicgame function.

Link to comment
Share on other sites

I think you just have a misplaced argument.

this.game.time.events.add(Phaser.Timer.SECOND * 6,1,BasicGame.Game.prototype.happyMsgSystem,this);

should be

this.game.time.events.add(Phaser.Timer.SECOND * 6, BasicGame.Game.prototype.happyMsgSystem, this);

You passed 1 in place of a callback.

Link to comment
Share on other sites

Hi,

first of all: thank you guys so far. I'm reading the text about "this" provided by symof. 

Intel XDK also creates a second file called app.js with this code:

(function () {
    /* globals Phaser:true, BasicGame: true */

   var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'game');

    game.state.add('Game', BasicGame.Game);

    game.state.start('Game');

})();

so, I'm working with 2 files and it confuses me.

I'll try Chazlodian's approach and post here the results.

 

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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