lee
May 12, 2020, 1:08am
1
I have a main scene with a number of sub-scenes (story dialog and mini-games). I’ve created a number of zones in my tile map to trigger the story scenes and mini-games. I’m having a couple of issues. When the player hits the zone the story starts as expected. However, when returning to the main scene.wake('thescene')
the player is still moving, likely because they were pressing the key to move when the entered the zone. The player will stop after the up button is pressed and released, then the scene carries on as normal.
How to I cancel the user input prior to launching the new scene.
How can can set the player position to a specified location (exit point) when the main scene loads.
The new position is saved in the object layer of the map, so I just wanted to pass a data package back notifying the main scene of the exit point. this.scene.wake('mainscene', { exitpoint: 'theexit'})
Where is the data accessed on the main scene, like what method is called when it wakes up?
Here is the callback on overlap for the zone to trigger the new scene:
() => {
if(this.player.data.values.entrance) return;
this.player.body.setVelocityY(0);
this.player.body.setVelocityX(0);
this.player.setData('entrance', 'complete');
this.scene.launch('story', { stage: 'entrance'});
this.scene.sleep();
}
When the child scene exits, I do something like this:
this.scene.stop();
this.scene.wake('mainscene', { exit: 'bumpercars_exit' });
Is there a better pattern to follow?
samme
May 12, 2020, 1:25am
2
How did you add the movement key input?
lee
May 12, 2020, 2:12am
3
In the create()
method of the scene:
this.left = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT);
this.right = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT);
this.up = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP);
this.down = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN);
Then in the update:
let animation = this.player.anims.currentAnim ? this.player.anims.currentAnim.key : 'down';
let speed = 75;
if(this.up.isDown) {
this.player.body.setVelocityY(speed * -1);
animation = 'walk-up';
} else if(this.down.isDown) {
this.player.body.setVelocityY(speed);
animation = 'walk-down';
} else {
this.player.body.setVelocityY(0);
}
if(this.left.isDown) {
this.player.body.setVelocityX(speed * -1);
animation = 'walk-left';
} else if(this.right.isDown) {
this.player.body.setVelocityX(speed);
animation = 'walk-right';
} else {
this.player.body.setVelocityX(0);
}
if( this.player.body.velocity.x === 0 && this.player.body.velocity.y === 0)
animation = animation.replace('walk-', '');
this.player.anims.play(animation, true);
this.player.body.velocity.normalize().scale(speed);
@samme might have a better solution but just taking a quick look at the docs it looks like keys have a reset()
method that will reset it back to the unpressed state: https://photonstorm.github.io/phaser3-docs/Phaser.Input.Keyboard.Key.html#reset__anchor
have not tested this but, in theory, you could reset all the player input keys when you do the scene wake
1 Like
samme
May 12, 2020, 4:24pm
5
Also try this.input.keyboard.resetKeys() in the scene that is sent to sleep.
2 Likes
samme
May 12, 2020, 4:33pm
6
I believe you can do this in scene create()
:
this.events.on('pause', this.input.keyboard.resetKeys, this.input.keyboard);
this.events.on('sleep', this.input.keyboard.resetKeys, this.input.keyboard);
1 Like
lee
May 12, 2020, 6:58pm
7
Yup, that did the trick.
Would this be the same mechanism to access the data on the wake event?
this.events.on('wake', this.onWake, this);
this.wake(sys, data) { do stuff with the data};
1 Like
lee
May 12, 2020, 7:23pm
9
Yes, just tested. That worked as well.
samme
August 30, 2020, 10:06pm
10
If you’re restarting the scene then you’ll want to avoid adding duplicate event handlers:
const { keyboard } = this.input;
this.events
.on('pause', keyboard.resetKeys, keyboard)
.on('sleep', keyboard.resetKeys, keyboard)
.once('shutdown', function () {
this.events
.off('pause', keyboard.resetKeys, keyboard)
.off('sleep', keyboard.resetKeys, keyboard);
}, this);
Below is just short form to help understand:
In another scene:
this.scene.wake(sceneName, {msg:“back from another scene”});
when this scene is awaken by the other scene:
this.events.on(‘wake’, function(sys, data){
console.log(data.msg);
});