Jump to content

[SOLVED] Typescript Method Undefined


cybearg
 Share

Recommended Posts

I'm following the "First Phaser Game" tutorial, which is made for JavaScript, and trying to convert it to TypeScript as I go, to see the parallels.

This is what I've got: http://pastebin.com/i4HCinRZ

Notice in the constructor that I have:

this.game = new Phaser.Game(800, 600, Phaser.AUTO, "content", { preload: this.preload, create: this.create, update: this.update });

... Where "this.preload", "this.create", and "this.update" all refer to methods in my Game class (not Phaser.Game -- it's my own Game class). That works just fine. However, down in the update method, I have:

game.physics.arcade.overlap(player, stars, this.collectStar, null, this);

... Which, one would think, would call the Game class's private collectStar method (the accessibility of the method doesn't matter, as I have the same issue when it's public or has default accessibility, btw), but instead this.collectStar is considered undefined when that method is called, and "this" apparently has an entirely different context than it does in the constructor.

I need to know how I can reference my collectStar method from within update(), passing it as a parameter to the overlap() function. Any insight, anyone?

If it helps, here's the compiled resulting .js: http://pastebin.com/0VjuZ74R

Link to comment
Share on other sites

Hi, change first line to this:

this.game = new Phaser.Game(800, 600, Phaser.AUTO, "content", this);

In the way you used it, you are passing as a state "special" object you just composed of this.preload, this.create and this.update methods. But it has no collectStars method.

Some time ago I wrote simple Phaser + Typescript tutorial here: http://sbcgamesdev.blogspot.cz/2015/05/phaser-tutorial-dronshooter-simple-game.html It is little old, but still valid. There is also shown how to structure game to keep it managable:

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class Game extends Phaser.Game {
    // -------------------------------------------------------------------------
    constructor() {
        // init game
        super(640, 400, Phaser.CANVAS, "content", State);
    }
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class State extends Phaser.State {

}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
window.onload = () => {
    new Game();
};

 

Link to comment
Share on other sites

There is a few methods, that Phaser recognizes. It checks if it is present in object you passed as state and if yes, it calls it. Look at this old post:

 In your case, when you put something inside { ...} then it is object. So, inside of your Game object, you are calling new Phaser.Game, but you are passing it anonymous object, that has preload, create and update methods - nothing more. You define its methods like preloader: this.preloader, which only says: "hey, for preloader method/function for this anonymous object use preloader method/function from my Game class". That anonymous object has only those three methods you defined - collectStar is missing. You can also modify your code like this and it will work:

this.game = new Phaser.Game(800, 600, Phaser.AUTO, "content", { preload: this.preload, create: this.create, update: this.update, collectStar: this.collectStar });

 Now, that object also has collectStar method. You could also create that object with mixing different methods from different objects: {preload: this.hello, create: other.someMyMethod, update: another.whatever, collectStar: myLibrary.collectStar}. With JS/TS, you can get pretty wild :D

 And what Phaser does with passed "State" object? It depends on what was passed to it:

        if (state instanceof Phaser.State)
        {
            newState = state;
        }
        else if (typeof state === 'object')
        {
            newState = state;
            newState.game = this.game;
        }
        else if (typeof state === 'function')
        {
            newState = new state(this.game);
        }

 In your case, second was used - this is why "game" reference appeared inside of your state. Later it also links other shortcuts automatically:

    link: function (key) {

        this.states[key].game = this.game;
        this.states[key].add = this.game.add;
        this.states[key].make = this.game.make;
        this.states[key].camera = this.game.camera;
        this.states[key].cache = this.game.cache;
        this.states[key].input = this.game.input;
        this.states[key].load = this.game.load;
        this.states[key].math = this.game.math;
        this.states[key].sound = this.game.sound;
        this.states[key].scale = this.game.scale;
        this.states[key].state = this;
        this.states[key].stage = this.game.stage;
        this.states[key].time = this.game.time;
        this.states[key].tweens = this.game.tweens;
        this.states[key].world = this.game.world;
        this.states[key].particles = this.game.particles;
        this.states[key].rnd = this.game.rnd;
        this.states[key].physics = this.game.physics;
        this.states[key].key = key;

    }

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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