11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour, je travaille actuellement sur un jeu de plateforme en Javascript. J'essaye notamment de mettre entre place un principe de collision. Cependant je fais face à des problèmes. Parmi les différentes plateformes que je crée seul la dernière à des collisions sur ses cotés (celles du dessous et du dessus fonctionnent pour toutes). De ce que j'ai pu voir, les conditions (l.100 à 112) sont bien lu et fonctionnelles pour chaque plateforme. Seulement le changement sur la variable collision n'est pas effectué (sauf sur la dernière plateforme crée). Je ne sais pas comment régler le problème et réclame votre aide. Je vous en remercie d'avance.

Voici la partie du code au centre de mon problème, suivi de l'entièreté de mon code actuel :

       if( player.position.x <= platform.position.x 
            && player.position.x + player.width >= platform.position.x 
            && player.position.x <= platform.position.x + platform.width 
            && player.position.y + player.height >= platform.position.y 
            && player.position.y <= platform.position.y + platform.height) {
                collision.right = false    
        } else {collision.right = true}
        if(player.position.x >= platform.position.x 
            && player.position.x <= platform.position.x + platform.width 
            && player.position.y + player.height >= platform.position.y 
            && player.position.y <= platform.position.y + platform.height) {
                collision.left = false    
        } else {collision.left = true}
    })

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

var img = new Image()
img.src = '/img/platform.png'

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

cvs.width = innerWidth
cvs.height = innerHeight

const gravity = 1
let jump = true

class Player {
    constructor() {
        this.position = {
            x: cvs.width / 2,
            y: cvs.height - 250
        }
        this.velocity = {
            x: 0,
            y: 20
        }
        this.width = 30
        this.height = 30
    }

    draw() {
        ctx.fillStyle = 'red'
        ctx.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 <= cvs.height) {
            this.velocity.y += gravity
            jump = false
        }
        else this.velocity.y = 0
    }
}

class Platform {
    constructor(x, y) {
        this.position = {
            x,
            y
        }

        this.image = img
        this.width = img.width
        this.height = img.height

    }

    draw() {
        ctx.drawImage(this.image, this.position.x, this.position.y)
    }
}

const platforms = [new Platform(900, 850), new Platform(0, 850)]
const player = new Player()
let collision = {
    right: true,
    left: true
}

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

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

    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
                jump = true
        }
        if(player.position.y >= platform.position.y + platform.height
            && player.position.y + player.velocity.y <= platform.position.y + platform.height
            && player.position.x + player.width >= platform.position.x 
            && player.position.x <= platform.position.x + platform.width) {
                player.velocity.y = 0
        }
        if( player.position.x <= platform.position.x 
            && player.position.x + player.width >= platform.position.x 
            && player.position.x <= platform.position.x + platform.width 
            && player.position.y + player.height >= platform.position.y 
            && player.position.y <= platform.position.y + platform.height) {
                collision.right = false    
        } else {collision.right = true}
        if(player.position.x >= platform.position.x 
            && player.position.x <= platform.position.x + platform.width 
            && player.position.y + player.height >= platform.position.y 
            && player.position.y <= platform.position.y + platform.height) {
                collision.left = false    
        } else {collision.left = true}
    })

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

    console.log(collision.right, collision.left)

    if(player.position.y >= innerHeight - 29) {
        jump = true
    }
}

animate()

addEventListener('keydown', ({keyCode}) => {
    switch (keyCode) {
        case 37: keys.left.pressed = true
            break
        case 39: keys.right.pressed = true
            break
        case 38: if(jump) {
            player.velocity.y -= 30
            jump = false
        }
            break
    }
})

addEventListener('keyup', ({keyCode}) => {
    switch (keyCode) {
        case 37: keys.left.pressed = false
            break
        case 39: keys.right.pressed = false
            break
    }
})


Modifié par Yuuno (25 Aug 2022 - 19:01)
Bonjour,

Je n'ai pas analysé le code en détail, je suppose que tes conditions pour détecter les collisions sont correctes.

Le problème peut venir du fait que tu écrases la valeur de collision.left ou collision.right dans ta boucle :
Par exemple, au premier tour de boucle pour détecter la collision avec la première plateforme, si la collision est bien détectée alors la valeur de collision.left ou collision.right sera passé à true.
Puis au second tour de boucle, si il n'y a pas de collision avec la seconde plateforme, alors la valeur de collision.left ou collision.right sera alors écrasé avec la valeur false.

Il faudrait peut-être sortir de la boucle dès qu'une collision est détectée, ou conserver l'état des collisions pour chaque plateforme.