How can I fix my player from jumping infinitely, and only allow two jumps, like a double jump. [vanilla JS]

My player can jump as many times as they want, and I only want to allow a double jump.

https://replit.com/@BluebayStudios/bluebaysonlyup


const canvas = document.querySelector('canvas')
const c = canvas.getContext('2d')

canvas.width = window.innerWidth
canvas.height = window.innerHeight

const gravity = 0.6

class Player {
    constructor() {
     this.position = {
        x: 100,
        y: 100
    }
    this.velocity = {
        x: 0,
        y: 1
    }
   this.width = 30
   this.height = 30
 }

    draw() {
       c.fillStyle = 'red'
       c.fillRect(this.position.x, this.
        position.y, this.width, this.height
        ) 
    }

    update()  {
        this.draw()
        this.position.y += this.velocity.y
        this.position.x += this.velocity.x

        if (this.position.y + this.height +
            this.velocity.y <= canvas.height)
            this.velocity.y += gravity
            else this.velocity.y = 0
    }
}
class Platform{
    constructor({ x, y}) {
    this.position = {
        x,
        y
    }

    this.width = 200
    this.height = 20
  }
  draw() {
    c.fillStyle = 'grey'
    c.fillRect(this.position.x, this.position.y, this.width, this.height)
  }
}

const player = new Player()
const platforms = [new Platform({
    x: 200, y: 100
}), new Platform({x:500, y:200 })]

const keys = {
    right: {
        pressed: false
    },
    left: {
        pressed: false
    },
}

function animate() {
    requestAnimationFrame(animate)
    c.clearRect(0, 0, canvas.width, canvas.height)
    player.update()
    platforms.forEach(platform => {
         platform.draw()
    })


    if (keys.right.pressed && player.position.x <400 ) {
        player.velocity.x = 5
    } else if (keys.left.pressed && player.position.x>100) {
        player.velocity.x = -5
    }else {
        player.velocity.x = 0

        if (keys.right.pressed) {
            platforms.forEach(platform => {
                platform.position.x -= 5
           })

        } else if (keys.left.pressed) {
            platforms.forEach(platform => {
                platform.position.x +=5
           })

        }
    }
    platforms.forEach((platform) => {

    if (player.position.y + player.height <= platform.position.y && 
        player.position.y + player.height + player.velocity.y >= 
        platform.position.y && player.position.x + player.width >= 
        platform.position.x && player.position.x <= platform.position.x + 
        platform.width) {
        player.velocity.y = 0
    }
})
}

animate()

window.addEventListener('keydown', ({ keyCode })=> {
switch (keyCode) {
    case 65:
        console.log('left')
        keys.left.pressed = true
        break

        case 83:
        console.log('down')
        break

        case 68:
        console.log('right')
        keys.right.pressed = true
        break

        case 87:
        console.log('up')
        player.velocity.y -=20
        break
}
})

window.addEventListener('keyup', ({ keyCode })=> {
    switch (keyCode) {
        case 65:
            console.log('left')
            keys.left.pressed = false
            break

            case 83:
            console.log('down')
            break

            case 68:
            console.log('right')
            keys.right.pressed = false
            break

            case 87:
            console.log('up')
            player.velocity.y = 0
            break
    }
    })

 

You need to create a condition where you check if the player is in the air and how many jumps he made since he touched the ground.

For example, here:

You can create a new att where you define a jump point in your constructor and the max jump (how many times the player can jump), like:

this.jumps = 0;
this.maxJumps = 2;

And in your update function:

You can update the counter

        if (this.position.y + this.height + this.velocity.y >= canvas.height) {
            this.velocity.y = 0;
            this.jumps = 0; // Here you reset the counter
        }
    }

    jump() {
        if (this.jumps < this.maxJumps) {
            this.velocity.y = -20;
            this.jumps++;
        }
        }

After that you adjust the events

window.addEventListener('keydown', ({ keyCode }) => {
    switch (keyCode) {
        case 87: // Like a 'W' key for jumping
            console.log('up');
            player.jump();
            break;
    }
});

// Remember to remove the up key 'keyup' event's action that sets the player's velocity.y to 0
window.addEventListener('keyup', ({ keyCode }) => {
    switch (keyCode) {
        case 87:
            // I really recommend that you don't reset the y velocity to 0 here to allow gravity to act after the jump
            console.log('up release');
            break;
    }
1 Like

Can I have a bit more help applying this to my script?

Sure, going by parts.

The player class:

class Player {
    constructor() {
        this.jumps = 0;
        this.maxJumps = 2;
    }

    update() {
        this.draw();
        this.position.y += this.velocity.y;
        this.position.x += this.velocity.x;

        if (this.position.y + this.height + this.velocity.y <= canvas.height) {
            this.velocity.y += gravity;
        } else {
            this.velocity.y = 0;
            this.jumps = 0;
        }
    }

    jump() {
        if (this.jumps < this.maxJumps) {
            this.velocity.y = -20;
            this.jumps++;
        }
    }
}

And for the event listeners:

window.addEventListener('keydown', ({ keyCode })=> {
    switch (keyCode) {

        case 87: // 'W' key for jump
            console.log('up');
            player.jump();
            break;

    }
});

window.addEventListener('keyup', ({ keyCode })=> {
    switch (keyCode) {

        case 87: // Remember to remove the action for 'W' key up
            console.log('up release');
            break;

    }
});

Thanks! I am just starting to learn javascript, so this helped a tremendous ton.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.