javascriptphaser-framework

cursors is not defined at Game.update (Phaser 3)


I'm currently learning Phaser and decided to use this Vite template (https://github.com/phaserjs/template-vite). These are the changes I've made:

import { Scene } from 'phaser';

export class Boot extends Scene
{
    constructor ()
    {
        super('Boot');
    }

    preload ()
    {
        this.load.image('background', 'assets/bg.png');
    }

    create ()
    {
        this.scene.start('Preloader');
    }
}
export class Game extends Scene
{
    constructor ()
    {
        super('Game');

        this.W = window.innerWidth;
        this.H = window.innerHeight;
    }
    create () {
        let player = this.add.rectangle(this.W / 2, this.H / 2, 25, 25, 0xfafafa);
        this.physics.add.existing(player);
        const cursors = this.input.keyboard.createCursorKeys();
        this.cameras.main.setBackgroundColor(0x0a0a0a);
    }

    update () {
        
        if (cursors.left.isDown) { // Error happens here
            player.body.setVelocityX(-20);
        }

    }
}

However, when I run it, this error occurs: Uncaught ReferenceError: cursors is not defined at Game.update (Game.js:26:9)

I've tried to make the player variable and the cursors variable global and in different places in the game.js file, but it didn't work. The error didn't change at all.


Solution

  • In your game.js file: You can't access a variable from another function/method, quick solution would be, to add the cursors to the this context.

    btw.: You would have to do the same for the player variable, or you will have the next error after solving this one.

    export class Game extends Scene
    {
        // ...
        create () {
            //...
            // instead of defining the variable in the `create function scope, 
            // add it to the scene context -> 'this'
            this.player = this.add.rectangle(this.W / 2, this.H / 2, 25, 25, 0xfafafa);
            // add you need to use 'this', when calling the property
            this.physics.add.existing(this.player);
            this.cursors = this.input.keyboard.createCursorKeys();
        }
    
        update () {
            // add you need to use 'this', when calling the property
            if (this.cursors.left.isDown) { 
               // add you need to use 'this', when calling the property
                this.player.body.setVelocityX(-20);
            }
        }
     }
    

    Info: when doing this you have to be careful, that you don't override existing properties.

    Or you could defined the varibales in the global scope (here some more info to scope), some think it is not as clean, but you avoid naming collisions and the usage of this:

    // define the variables in the global Scope
    let player;
    let cursors;
    
    export class Game extends Scene
    {
        // ...
        create () {
            //...
            // now you can access them from anywhere, beware not to use 
            // let, var or const, since this redefines them in a local scope
            player = this.add.rectangle(this.W / 2, this.H / 2, 25, 25, 0xfafafa);
            this.physics.add.existing(player);
            cursors = this.input.keyboard.createCursorKeys();
        }
    
        update () {
            if (cursors.left.isDown) { 
                player.body.setVelocityX(-20);
            }
        }
     }