Character stops moving and stays stuck after pressing Jump (SPACEBAR)

Hello! I am currently doing a 2D topdown game similarly to the old Pokemon games and I am pretty new to the whole coding and game developing thing (I’m only doing it because it’s part of my course that I am currently taking in my university)

anyway, would anyone know why my character stays stuck after I press jump?

heres a link to the project: PlayCanvas | HTML5 Game Engine

and heres my movement code for my character:

var Movement = pc.createScript('sillyScript');

// initialize code called once per entity
Movement.prototype.initialize = function() {
    // Store a reference to the sprite component to avoid looking it up every frame
    this.spriteComponent = this.entity.sprite;
    // Define the movement speed
    this.speed = 3; // Adjust this value as needed for 2D movement (for 7 FPS animation)
    // Define the jump force
    this.jumpForce = 300; // Adjust this value as needed for 2D jumping
    // Track the current movement direction
    this.currentDirection = new pc.Vec2(0, 0);
    // Track whether the entity is currently jumping
    this.isJumping = false;
    // Track whether the jump animation is playing
    this.isJumpAnimationPlaying = false;

    // Subscribe to the physics landing event
    this.entity.rigidbody.on('collisionend', this.onLanding, this);
};

// update code called every frame
Movement.prototype.update = function(dt) {
    var movementX = 0;
    var movementY = 0;

    // Check for movement keys and set the movement direction
    if (this.app.keyboard.isPressed(pc.KEY_W) || this.app.keyboard.isPressed(pc.KEY_UP)) {
        movementY = 1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_S) || this.app.keyboard.isPressed(pc.KEY_DOWN)) {
        movementY = -1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_D) || this.app.keyboard.isPressed(pc.KEY_RIGHT)) {
        movementX = 1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_A) || this.app.keyboard.isPressed(pc.KEY_LEFT)) {
        movementX = -1;
    }

    // Normalize the movement direction to prevent faster diagonal movement
    if (movementX !== 0 && movementY !== 0) {
        movementX *= 0.7071;
        movementY *= 0.7071;
    }

    // Jump logic
    if ((this.app.keyboard.wasPressed(pc.KEY_SPACE) || this.app.keyboard.wasPressed(pc.KEY_UP)) && !this.isJumping) {
        this.isJumping = true;
        // Apply the jump force
        this.entity.rigidbody.applyImpulse(0, this.jumpForce, 0);
        // Play the jump animation when jump is initiated
        this.entity.sprite.play("sillyJump", 1, this.onJumpAnimationEnd.bind(this));
        this.isJumpAnimationPlaying = true;
    }

    // Play the appropriate animation based on the movement direction
    if (this.isJumpAnimationPlaying) {
        // If the jump animation is playing, do not override it
        return;
    } else if (this.isJumping) {
        // If jumping, do not override the jump animation
        this.entity.sprite.play("sillyJump");
    } else if (movementY > 0) {
        this.entity.sprite.play("sillyUp");
    } else if (movementY < 0) {
        this.entity.sprite.play("sillyDown");
    } else if (movementX > 0) {
        this.entity.sprite.play("sillyRight");
    } else if (movementX < 0) {
        this.entity.sprite.play("sillyLeft");
    } else {
        // If no movement keys are pressed, play the idle animation
        this.entity.sprite.play("sillyIdle");
    }

    // Update the current movement direction
    this.currentDirection.set(movementX, movementY);

    // Move the entity based on the accumulated movement
    this.entity.translate(this.currentDirection.x * this.speed * dt, this.currentDirection.y * this.speed * dt, 0);
};

// Method to reset the jump flag after the jump animation is finished
Movement.prototype.onJumpAnimationEnd = function() {
    this.isJumping = false;
    this.isJumpAnimationPlaying = false;
};

// Method to reset the mid-air flag after the entity lands
Movement.prototype.onLanding = function(event) {
    // Check if the entity has landed on a surface (not in mid-air)
    if (event.other && event.other.tags.has('ground')) {
        this.isJumping = false;
        this.isJumpAnimationPlaying = false;
    }
};

// swap method called for script hot-reloading
// inherit your script state here
// SillyScript.prototype.swap = function(old) { };

// to learn more about script anatomy, please read:
// https://developer.playcanvas.com/en/user-manual/scripting/

any help would be greatly appreciated, thank you!

1 Like

Would it be possible to share the full project?

It’s not just that the character can’t move, the animation also stops and there is no error message in the console.

1 Like

sure! how? will I add you to the team in the project?

I was expecting just a public link so anyone can check it. Maybe duplicate it and remove everything but the character.

1 Like

https://playcanvas.com/editor/project/1103441

hope this is it!

1 Like

I can see it, checking

The animation stops completely, so I think this.isJumpAnimationPlaying and/or this.isJumping are still true. Because there is no animation, even the jump while being idle, I think at the very least this.isJumpAnimationPlaying = true

Maybe add console.debug("this.isJumpAnimationPlaying: ", this.isJumpAnimationPlaying); and console.debug("this.isJumping: ", this.isJumping); in line 59 before this block to confirm

Just guessing, but in line 19, maybe we want to use collisionstart instead of collisionend?

In lines 89 and 95 you may want to add console.debug('onJumpAnimationEnd executing); and console.debug('onLanding executing') to debug.

Also, you have duplicated code (lines 89-90 and 97-98). The error is not because of this, but you may want to clear it up.

hello, tried updating the code with what you suggested, my character cannot move around anymore?

var Movement = pc.createScript('sillyScript');

// initialize code called once per entity
Movement.prototype.initialize = function() {
    // Store a reference to the sprite component to avoid looking it up every frame
    this.spriteComponent = this.entity.sprite;
    // Define the movement speed
    this.speed = 3; // Adjust this value as needed for 2D movement (for 7 FPS animation)
    // Define the jump force
    this.jumpForce = 300; // Adjust this value as needed for 2D jumping
    // Track the current movement direction
    this.currentDirection = new pc.Vec2(0, 0);
    // Track whether the entity is currently jumping
    this.isJumping = true;
    // Track whether the jump animation is playing
    this.isJumpAnimationPlaying = true;

    // Subscribe to the physics landing event
    this.entity.rigidbody.on('collisionstart', this.onLanding, this);
};

// update code called every frame
Movement.prototype.update = function(dt) {
    var movementX = 0;
    var movementY = 0;

    // Check for movement keys and set the movement direction
    if (this.app.keyboard.isPressed(pc.KEY_W) || this.app.keyboard.isPressed(pc.KEY_UP)) {
        movementY = 1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_S) || this.app.keyboard.isPressed(pc.KEY_DOWN)) {
        movementY = -1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_D) || this.app.keyboard.isPressed(pc.KEY_RIGHT)) {
        movementX = 1;
    }

    if (this.app.keyboard.isPressed(pc.KEY_A) || this.app.keyboard.isPressed(pc.KEY_LEFT)) {
        movementX = -1;
    }

    // Normalize the movement direction to prevent faster diagonal movement
    if (movementX !== 0 && movementY !== 0) {
        movementX *= 0.7071;
        movementY *= 0.7071;
    }

    // Jump logic
    if ((this.app.keyboard.wasPressed(pc.KEY_SPACE) || this.app.keyboard.wasPressed(pc.KEY_UP)) && !this.isJumping) {
        this.isJumping = true;
        // Apply the jump force
        this.entity.rigidbody.applyImpulse(0, this.jumpForce, 0);
        // Play the jump animation when jump is initiated
        this.entity.sprite.play("sillyJump", 1, this.onJumpAnimationEnd.bind(this));
        this.isJumpAnimationPlaying = true;
    }

    // Play the appropriate animation based on the movement direction
    console.debug("this.isJumpAnimationPlaying: ", this.isJumpAnimationPlaying);
    console.debug("this.isJumping: ", this.isJumping);

    if (this.isJumpAnimationPlaying) {
        // If the jump animation is playing, do not override it
        return;
    }

    if (this.isJumping) {
        // If jumping, do not override the jump animation
        this.entity.sprite.play("sillyJump");
    } else if (movementY > 0) {
        this.entity.sprite.play("sillyUp");
    } else if (movementY < 0) {
        this.entity.sprite.play("sillyDown");
    } else if (movementX > 0) {
        this.entity.sprite.play("sillyRight");
    } else if (movementX < 0) {
        this.entity.sprite.play("sillyLeft");
    } else {
        // If no movement keys are pressed, play the idle animation
        this.entity.sprite.play("sillyIdle");
    }

    // Update the current movement direction
    this.currentDirection.set(movementX, movementY);

    // Move the entity based on the accumulated movement
    this.entity.translate(this.currentDirection.x * this.speed * dt, this.currentDirection.y * this.speed * dt, 0);
};

// Method to reset the jump flag after the jump animation is finished
Movement.prototype.onJumpAnimationEnd = function() {
    console.debug('onJumpAnimationEnd executing');
    this.isJumping = truess;
    this.isJumpAnimationPlaying = true;
};

// Method to reset the mid-air flag after the entity lands
Movement.prototype.onLanding = function(event) {
    // Check if the entity has landed on a surface (not in mid-air)
    if (event.other && event.other.tags.has('ground')) {
        console.debug('onLanding executing');
        this.isJumping = true;
        this.isJumpAnimationPlaying = true;
    }
};

// swap method called for script hot-reloading
// inherit your script state here
// SillyScript.prototype.swap = function(old) { };

// to learn more about script anatomy, please read:
// https://developer.playcanvas.com/en/user-manual/scripting/

I’ll take a look later today, but to debug it yourself try to change back to collisionend and read the logs from the console.

will do. thank you! hoping to hear from you soon