Jump to content

State.update() is never called


Cybermage
 Share

Recommended Posts

Hey everyone, it's my first time posting here, but I've dabbled in Phaser quite a bit in the past. I've been struggling for a couple of hours now to get my game accepting input, but to no avail...

I'm using brunch.io as build system and had some difficulty getting Phaser working in the first place, but at this point it renders fine and there are no errors in the console, but the update() method of my only game state is never called. I'm probably just being dumb, so I'd really appreciate it if someone can enlighten me.

Here's the code for my main method:

'use strict';

const SCREEN_WIDTH = window.innerWidth;
const SCREEN_HEIGHT = window.innerHeight - 4;

var Client = require('client');

document.addEventListener('DOMContentLoaded', () => {
    console.log('Initialized 1000 Suns!!!');

    var game = new Phaser.Game(SCREEN_WIDTH, SCREEN_HEIGHT, Phaser.AUTO, 'app');
    var clientState = new Client();
    game.state.add('main', clientState);  
    game.state.start('main');
});

 

And my main game state:

'use strict';

const CELL_SIZE = 128;
const SPRITE_SIZE = 64;
const SCREEN_WIDTH = window.innerWidth;
const SCREEN_HEIGHT = window.innerHeight - 4;
const GRID_WIDTH = 100;
const GRID_HEIGHT = 100;
const WORLD_WIDTH = GRID_WIDTH * CELL_SIZE;
const WORLD_HEIGHT = GRID_HEIGHT * CELL_SIZE;
const CAMERA_SPEED = 16;

var Galaxy = require('galaxy');

var Client = function() {
    Phaser.State.call(this);

    this.galaxy = new Galaxy(1000, GRID_WIDTH, GRID_HEIGHT);
}

Client.prototype = Object.create(Phaser.State.prototype);
Client.prototype.constructor = Client;

Client.prototype.preload = function() {
    console.log('Preloading');
    this.game.load.atlasJSONHash('sprites', 'art/sprites.png', 'art/sprites.json');
}

Client.prototype.create = function() {
    console.log('Creating');
    this._createStarSprites();
    
    this.game.world.setBounds(0, 0, WORLD_WIDTH, WORLD_HEIGHT);

    this.cursors = this.game.input.keyboard.createCursorKeys();
    console.log('Creating done..');
}

Client.prototype.update = function() {
    console.log('Never called...');
}

Client.prototype.render = function() {
    console.log('Called a lot...');
}

Client.prototype._createStarSprites = function() {
    for (let key in this.galaxy.stars) {
        var parts = key.split(",");
        var x = parseInt(parts[0]);
        var y = parseInt(parts[1]);
        var star = this.galaxy.stars[key];

        var pixelX = x * CELL_SIZE + (CELL_SIZE / 2) - SPRITE_SIZE * star.getScale() / 2;
        var pixelY = y * CELL_SIZE + (CELL_SIZE / 2) - SPRITE_SIZE * star.getScale() / 2;
        var sprite = this.game.add.sprite(pixelX, pixelY, 'sprites', star.getColour());

        sprite.scale.x = star.getScale();
        sprite.scale.y = star.getScale();
    }
}

module.exports = Client;

 

Link to comment
Share on other sites

  • 2 weeks later...

After digging around in the source a bit and tracing through the code a bit in the debugger it seems that in RequestAnimationFrame.js, the _onLoop function is somehow being called by window.requestAnimationFrame with an undefined value for time. It's the else branch in this snippet below:

    start: function () {

        this.isRunning = true;

        var _this = this;

        if (!window.requestAnimationFrame || this.forceSetTimeOut)
        {
            this._isSetTimeOut = true;

            this._onLoop = function () {
                return _this.updateSetTimeout();
            };

            this._timeOutID = window.setTimeout(this._onLoop, 0);
        }
        else
        {
            this._isSetTimeOut = false;

            this._onLoop = function (time) {
                return _this.updateRAF(time);
            };

            this._timeOutID = window.requestAnimationFrame(this._onLoop);
        }

    }

 

It looked like this might be causing Game.update() to never get into one of the branches where this.updateLogic() is called (which in turn calls state.update()).

Link to comment
Share on other sites

Thanks for the help! 

I just tried that, but it didn't seem to have any effect. It did get me digging into how the states are initialized and it seems that Phaser.State() would be called with a game parameter by the StateManager provided you added the state like this:

game.state.add('main', Client);  

Instead of like this as I had it:

game.state.add('main', new Client());

However when I looked at State's constructor function I found that it actually takes no parameters... the magic that sets the game on the Stage is actually in StateManager.link() which seems to have been working perfectly all along.

 

I then went back to my theory about RequestAnimationFrame not working properly and saw in Game.js that you could pass a configuration object to Game's constructor instead of individual arguments and that if I did that I could toggle the forceSetTimeOut option on RAF. So I changed from this:

var game = new Phaser.Game(SCREEN_WIDTH, SCREEN_HEIGHT, Phaser.AUTO, 'app');

To this:

var game = new Phaser.Game({
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
    renderer: Phaser.AUTO,
    parent: 'app',
    forceSetTimeOut: true
});

And now it works!

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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