Search code examples
javascripthtml5-canvas2dcollision-detectiongame-physics

Collision detection conditions not working when the item's Y is 0 in JS


in the code I am trying to simulate the movement of a ball with velocity in x direction and also gravity in the 2D world. Everything seems to work fine and the ball is bouncing until it reaches the ground then the condition for the collision detection with the walls of that box won't work and the ball rolls out of the screen.

I have shared the full code in this link: https://jsfiddle.net/tahajalili/bhqurw5g/3/ I am quite a newbie in this field, so can anyone help me with this?

but the JavaScript code is like this:

var canvas = document.getElementById('gameScreen');
var ctx = canvas.getContext('2d');

//world 
var width = 800;
var heigth = 800;
var gravity = 9.8;
var fps = 1/40;
var e = 0.8;

//Object
function Ball(x, y, velocity, dy, radius, mass, color){
    this.x = x;
    this.y = y;
    this.vy = velocity;
    this.vx = velocity;
    this.dy = dy;
    this.mass = mass;
    this.r = radius;
    this.color = color;
    
    this.update = function(){
        var ay = gravity;
        if(this.y + radius > heigth){
            this.vy = -this.vy;
            this.vy *= e;            
        }
        else if(this.x + this.r > width){
            this.vx = -this.vx;
        }
        else if (this.x - this.r < 0) {
            this.vx = -this.vx;
        }        
        else{
            this.vy += ay * fps;            
        }
        this.y += this.vy *fps*100;
        this.x += this.vx;
        this.draw();
    }

    this.draw = function(){
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }  
}

//working functions
function init(){
    b = new Ball(30, heigth-500, 7, 1, 30, 0.1, 'red');
}

function animate(){
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,width,heigth);
    b.update();
}

init();
animate();

Solution

  • You made your right collision test depend on the floor collision test by using else if.

    You probably would have not made that mistake if you had labelled your predicates

    this.update = function () {
        const floorCollision = this.y + this.r > heigth;
        const rightCollision = this.x + this.r > width;
        const leftCollision = this.x - this.r < 0
        const xCollision = rightCollision || leftCollision;
    
        if (floorCollision) {
            this.vy *= -1;
            this.vy *= e;
        } else {
            this.vy += gravity * fps;
        }
    
        if (xCollision) {
            this.vx *= -1;
        }
    
        this.y += this.vy * fps * 100;
        this.x += this.vx;
    
        this.draw();
    }