Why does the condition not apply to all of my buildings?

Viewed 34

I am currently working a 2d HTML Canvas game, and I came across a big problem. When the player walks into the sides of the building, their x-velocity, or y-velocity, should become 0 and their position should stay in place as long as they keep pressing the same key. While these conditions do work, they only work for the last building rendered. I have a feeling it may have to do with my player class, but I'm not exactly sure where to start.

This is one of the conditions from the building

// Works, but only works for the last building rendered
// Using forEach to apply the conditions for every building

if (player.position.y + player.spriteHeight >= building.position.y &&
    player.position.y <= building.position.y + building.image.height - player.spriteHeight - 1 &&
    player.position.x + player.spriteWidth <= building.position.x &&
    player.position.x + player.spriteWidth + player.velocity.x >= building.position.x) {
            leftCollision = true
            player.velocity.x = 0
            player.position.x = building.position.x - player.spriteWidth
        }
else {
            leftCollision = false
        }

This is being passed into the canvas file from the level file

export const buildings = [
    new Building({ image: building1_image, x: 100, y: 100 }), // does not work
    new Building({ image: building1_image, x: 200, y: 200 }) // works on this one
]

The Building Class

export class Building {
    constructor({ image, x, y }) {
        this.position = {
            x: x,
            y: y
        }
        this.image = image
    }
    draw() {
        c.drawImage(this.image, this.position.x, this.position.y)
    }
}

The Player Class

export class Player {
    constructor({ image, x, y }) {
        this.position = {
            x: x,
            y: y
        }
        this.velocity = {
            x: 0,
            y: 0
        }
        this.image = image
        this.cols = 3
        this.spriteWidth = this.image.width / this.cols
        this.spriteHeight = this.image.height
        this.totalFrames = 3
        this.currentFrame = 0
        this.srcX = 0
        this.srcY = 0
        this.framesDrawn = 0
    }
    draw() {
        this.currentFrame = this.currentFrame % this.totalFrames
        this.srcX = this.currentFrame * this.spriteWidth
        c.drawImage(
            this.image,
            this.srcX,
            this.srcY,
            this.spriteWidth,
            this.spriteHeight,
            this.position.x,
            this.position.y,
            this.spriteWidth,
            this.spriteHeight)
    }
    update() {
        this.framesDrawn++
        if (this.framesDrawn >= 10) {
            this.currentFrame++
            this.framesDrawn = 0
        }
        this.draw()
        this.position.x += this.velocity.x
        this.position.y += this.velocity.y
    }
}

Problem Demonstration: https://imgur.com/a/7lV6wmv

EDIT: This is the full snippet of the condition

world.buildings.forEach(building => {
        const player = world.player

        if (player.position.y + player.spriteHeight >= building.position.y &&
            player.position.y <= building.position.y + building.image.height - player.spriteHeight - 1 &&
            player.position.x + player.spriteWidth <= building.position.x &&
            player.position.x + player.spriteWidth + player.velocity.x >= building.position.x) {
            leftCollision = true
            player.velocity.x = 0
            player.position.x = building.position.x - player.spriteWidth
        }
        else {
            leftCollision = false
        }
    })
1 Answers

leftCollision should have a default value of true and update it only when it's false. This way it will prevent a building from overriding the status of another.

Related