[Help] Cameras.Controls.SmoothedKeyControl refuses to work

I’m trying to make a game where the camera moves around, and I found this example which had a nice camera using SmoothedKeyControl. I brought what seemed to be the camera code over and changed the vars to lets because I’d read somewhere that let was safer and causes fewer confusing errors.

let controls;

function create ()
{
    let cursors = this.input.keyboard.createCursorKeys();
    let controlConfig = {
        camera: this.cameras.main,
        left: cursors.left,
        right: cursors.right,
        up: cursors.up,
        down: cursors.down,
        acceleration: 0.02,
        drag: 0.0005,
        maxSpeed: 0.7
    };

    controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}

function update (time, delta)
{
    controls.update(delta);
}

And it didn’t work. TypeError: Cannot read properties of undefined (reading 'update')
I didn’t know what was wrong, so I just went back and copied everything that had looked like it had anything to do with the camera to see if that would work. This is what my code looks like now.

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    //backgroundColor: '#2d2d2d',
    //parent: 'phaser-example',
    /*pixelArt: true,*/
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var controls;

let game = new Phaser.Game(config);


function preload() {
    this.load.image('tiles', 'api/tilemap');
    this.load.image('marioTiles',"https://labs.phaser.io/assets/tilemaps/tiles/super-mario.png")
}

async function create() {
    //----------------------------------------------------------------------------------------------------------------------    
    let fullGameData;
    await fetch("api/fullGameData")
    .then((response) => {
            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            return response.json();
        }
    )
    .then((json) => {
        console.log("test= " + json);
        fullGameData = json;
        //createContinued1(json);
    })

    let map = this.make.tilemap({ data: fullGameData.map, tileWidth: 188, tileHeight: 176, orientation: "hexagonal", staggeraxis: "y", staggerindex: "odd", hexsidelength: 100 });
    let tiles = map.addTilesetImage('tiles');
    let mainLayer = map.createLayer(0, tiles, 0, 0);
    
    //cameracontrols -----------------------------------------------------------------------------------------------------------
    var cursors = this.input.keyboard.createCursorKeys();

    this.cameras.main.setZoom(2);
    this.cameras.main.centerOn(200, 100);

    var controlConfig = {
        camera: this.cameras.main,
        left: cursors.left,
        right: cursors.right,
        up: cursors.up,
        down: cursors.down,
        acceleration: 0.02,
        drag: 0.0005,
        maxSpeed: 0.7
    };

    controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}

function update (time, delta)
{
    controls.update(delta);
}

And it still doesn’t work. Same error: TypeError: Cannot read properties of undefined (reading 'update')
The weird thing is, though, the example that I’m basing off of is perfectly functional, and I don’t know what I have in my code that’s breaking the camera.
Maybe I’m just being dumb. If someone could point out what’s causing this error, that’d be really helpful :slight_smile:

:wave:

The first code block worked correctly for me, no errors. Double-check that create() is getting called.

Re. the second code block, async won’t make update() wait. Remove the async, and use load.json() in preload() instead.

1 Like

Thanks, it works now :smiley:

On a side note, is there a way I can make update() not get called until create() is over or is this just how Phaser works? Or is the await screwing it somehow? I don’t get why having the await breaks the code, doesn’t await wait until the async function ends? Javascript is confusing lol :slight_smile:

update() isn’t called until create() has returned, but Phaser doesn’t know or care about any async processes you start during create(). :slight_smile:

await doesn’t prevent a function from returning synchronously.

1 Like

I’m still confused. The docs say await pauses the execution of its surrounding function, does that mean a function can return synchronously while being paused?

Source: developer.mozilla.org, “await is usually used to unwrap promises by passing a Promise as the expression . Using await pauses the execution of its surrounding async function until the promise is settled (that is, fulfilled or rejected).”

Maybe I shouldn’t say return. await pauses the execution of the async function it’s within, then control is yielded back to the calling function. So here, await pauses the execution of create(), control is yielded back to Phaser, which isn’t using await and continues as usual.

1 Like

Oh, so when I call await in create(), Phaser thinks that create() has finished executing because control is given back to Phaser?

Yes.

Because await is only valid inside async functions and modules, which themselves are asynchronous and return promises, the await expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the await expression.

await

1 Like

Gotcha. Thanks! :smiley: