toytoytoytoytoy

{SOLVED} - Game Object Becoming Undefined - TypeScript and Phaser

Recommended Posts


class WoodWorldGame {
    Time: number;
    Tiles: TetrisActors.QTile[];
    Game: Phaser.Game;
    TileFactory: TetrisActors.QTileFactory;
    constructor() {
        this.Game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', { preload: this.preload, create: this.create, update: this.update});
        this.TileFactory = new TetrisActors.QTileFactory(this.Game);
        this.Time = 0;
    }

    preload() {
        this.Game.load.spritesheet('QTileSheet', 'img/sheet1.png', 32, 32);
    }

    create() {

        for (var i = 0; i < 10; i++) {
            this.Tiles.push(this.TileFactory.CreateTile(TetrisActors.QTileType.ACORN, i*32, 0));
        }
    }
    update() {
        if (this.Time == 800) {
            this.Tiles[0].Kill();
            this.Tiles[0] = this.TileFactory.CreateTile(TetrisActors.QTileType.BARK, 333, 332);
        }

    }
}

window.onload = () => {
   var game = new WoodWorldGame();
};

When I execute this code, it breaks during preload() with the message "Uncaught TypeError: Cannot read property 'load' of undefined"

I've tried stepping through function by function in the Chrome console trying to find when it becomes undefined, but I can't find it exactly. I think it has something to do with the life of the WoodWorldGame object, but I could be grasping at straws,

Any help you could offer would be so so so appreciated, thanks.

-toy

 

Share this post


Link to post
Share on other sites

I don't know TypeScript, but because no one else has responded, I'll give it a shot.

 

If this.Game is undefined in preload, I suspect the context of preload is being set incorrectly. Not sure how to fix this in TypeScript, or why it's happening in the first place, but that's where I'd start.

Share this post


Link to post
Share on other sites

In your place, I would clearly split game and state objects like this:

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

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

}

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

Note, that your Game clearly extends Phaser.Game and calls super constructor with your new State, that extends Phaser.State. You can then put your preload method into State class - for example like this:

class State extends Phaser.State {

    // -------------------------------------------------------------------------
    preload() {
        // background image
        this.game.load.image("BG", "bg.jpg");
        // load sprite images in atlas
        this.game.load.atlas("Atlas", "atlas.png", "atlas.json");
    }
}

Some time ago I wrote 3 part tutorial on building simple Phaser game in Typescript. It is enough to follow part 1 to build minimal working example: http://sbcgamesdev.blogspot.cz/2015/05/phaser-tutorial-dronshooter-simple-game.html

Share this post


Link to post
Share on other sites

The problem ended up being some vaguery of 'this' in context. I changed the function definition that was accessing this.game to the format foo = () => { logic; }, which in TypeScript is the equivalent of setting "_this = this" outside of a closure, then within the closure using '_this' to maintain the correct context.

Weird problem, weird answer, but '= () =>' solved all my problems

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.