Phaser error on first load of game undefined varia

2019-09-15 05:07发布

问题:

When I run my game in Google Chrome and Firefox, the game screen is black, once I refresh it, it runs as it should.

The error I see in the console when the screen is black is:

TypeError: paddle is undefined (Firefox)

Uncaught TypeError: Cannot read property 'x' of undefined (Chrome)

I also have a warning:

Phaser.Loader - active loading canceled / reset (Firefox & Chrome)

The relevant part of my code is:

var game = new Phaser.Game(800, 560, Phaser.AUTO, 'phaser-canvas', { preload: preload, create: create, update: update });

function setUpLevel(i) {
    $.getJSON("levels.json", function(json) {
            paddle.x = json.levels[i].paddle_startX;
    });
}

function processPaddle() {
    var paddle_loc = paddle.x + 80
}

function preload() {    
    //>Game assets
    game.load.image('paddle', 'assets/img/Paddle.png');

    // Load JSON file describing the level
    game.load.json('levels', 'levels.json');
}

//Paddle
var paddle;
var paddle_vel;

var json;

// The function below will be automatically invoked by Phaser when
// the assets in the preload() function finished loading

function create() {
    game.load.reset(true);

    var json = game.cache.getJSON('levels');

    // Enque the load of the background images found inside the level file

    for (var i = 0; i < json.levels.length; i++) {
        game.load.image('background' + i.toString(), json.levels[i].background);
    }

    // Specify loadComplete() as a callback to be called when all assets finished loading

    game.load.onLoadComplete.add(loadComplete, this);

    // Load the newly enqued assets

    game.load.start();
}

// The function below will be automatically invoked by Phaser when
// the assets in the create() function finished loading

function loadComplete() {
    json = game.cache.getJSON('levels');

    game.physics.startSystem(Phaser.Physics.ARCADE);

    paddle = mid_layer.create(100, 400, 'paddle');
    game.physics.enable(paddle, Phaser.Physics.ARCADE);

    paddle.scale.setTo(0.7, 0.7);
    paddle.body.immovable = true;
    paddle.body.collideWorldBounds = true;

    setUpLevel(current_level);    
}

 function update() {
        processPaddle();
 }

I guess the error is because the loadComplete() function hasn't finished yet, and the update() function has started, which uses the paddle variable, which hasn't been assigned a value yet - But I'm not sure.

回答1:

The update function will start firing as soon as create completes, but in your case the paddle doesn't exist by that point, so errors will start being thrown. I would suggest you break your game down into States, a 'Boot' state could load your json + preloader assets, and then you can swap to a 'Preloader' state which pulls in all the assets you need (as read from the json). Upon completion you can move to a Game state or similar. It would help keep things cleaner (logically) for you as well.



回答2:

Agreed with the previous answer - you should look into breaking down your game into states. What happens when you create the game with var game = new Phaser.Game(800, 560, Phaser.AUTO, 'phaser-canvas', { preload: preload, create: create, update: update });

You are inserting an object that runs the 'preload', 'create', and 'update' functions. Your function processPaddle() is outside of that object as you are setting the functions in that object to be equal to the functions of the same name in the code below.

If you had your code set up in State objects, you'd be able to include processPaddle() and refer to with a this.processPaddle().

You could probably correct it as is by changing { preload: preload, create: create, update: update } to { preload: preload, create: create, update: update, processPaddle: processPaddle } in your first line.