I'm working on animating a character (using a texture atlas) with user input in Phaser 3 and I'm running into an issue with the animation not stopping when I release the respective arrow button. I've tried a few tactics, and some of them only partially work. The code below is what I use which works as intended in all respects, except the animation doesn't stop after I release the respective arrow key. Maybe I need logic with stopping animation once the key is lifted? Any suggestions? Thanks!
I've used this post as an example, but it prevents the character from moving diagonally: Sprite Sheet animation with arrow keys
update() {
this.hero.setVelocity(0,0);
if (this.cursors.up.isDown) {
this.hero.anims.play('walkUp', true);
this.hero.setVelocityY(-200);
}
else if (this.cursors.down.isDown) {
this.hero.anims.play('walkDown', true)
this.hero.setVelocityY(200);
}
if (this.cursors.left.isDown) {
this.hero.anims.play('walkLeft', true)
this.hero.setVelocityX(-200);
}
else if (this.cursors.right.isDown) {
this.hero.anims.play('walkRight', true)
this.hero.setVelocityX(200);
}
}
There are many ways to solve this. Your solution is ofcourse vaild, but here two alternative, the would keep your code abit shorter an easier to read.
Update: After re-reading your question, I see that for your specific useCase the Alternative 2 would be the needed solution. Just adding those 3 lines to your initial code, should do the trick.
Alternative 1
Since movement to the left and right override the up and down movement you could simply reorder the if/else
blocks and chain them all as ob big if/else
block and stop the animation in the final else
. (Me from the future, your if's
only override the animation)
update() {
this.hero.setVelocity(0,0);
if (this.cursors.left.isDown) {
this.hero.anims.play('walkLeft', true)
this.hero.setVelocityX(-200);
}
else if (this.cursors.right.isDown) {
this.hero.anims.play('walkRight', true)
this.hero.setVelocityX(200);
}
else if (this.cursors.up.isDown) {
this.hero.anims.play('walkUp', true);
this.hero.setVelocityY(-200);
}
else if (this.cursors.down.isDown) {
this.hero.anims.play('walkDown', true)
this.hero.setVelocityY(200);
}
else {
this.hero.anims.stop();
}
}
Alternative 2
Just check at the end of the update
function, if the velocity
-length is more or less equal to zero. (Since the object often don't really stop (because of gravity, gliding and some physics round stuff ) < 2
should be save/okay to use)
update() {
// ... your initial code
if (this.hero.body.velocity.length() < 2) {
this.hero.anims.stop();
}
}
In personally like the first altertive, but depending on your usecase, if you need to handle up/down and left/right independently, the later should be fine also.
Improved Alternative 2 but slightly longer, you could check for the key events instead of the
velocity
-length and it would be "cleaner".
if (!this.cursors.up.isDown &&
!this.cursors.down.isDown &&
!this.cursors.left.isDown &&
!this.cursors.right.isDown ){
this.hero.anims.stop();
}