Search code examples
javascriptboxcollider

How to know in which side the collision has occured in Javascript?


Im writing a practice script where i animate a bunch of boxes and detect collision and then move them accordingly. Problem is, i found the collision but how to check in which side the collision has occurred so i can move them accordnigly.

This is the method i wrote.Is there a better way to do it?

this.ballCollide = function(){
for(var i = 0; i < ball.length; i++){
  for(var j = i+1 ; j < ball.length; j++){
    if( ((ballX[i] + 50) >= ballX[j]) && (ballX[i] <= (ballX[j] + 50)) && ((ballY[i] + 50) >= ballY[j]) && (ballY[i] <= (ballY[j] + 50))){
       movePosX[i] = -movePosX[i];
       movePosY[i] = -movePosY[i];
       movePosX[j] = -movePosX[j];
       movePosY[j] = -movePosY[j];
    }
  }
}

}


Solution

  • I think a little refactoring is in order. The following might help point you in the right direction:

    NOTE: I didn't validate the code, so read every character. Plus, I think the left and right are set up, but didn't work through the top / bottom nor the final moving logic because I don't think I understood the original logic (or at least it started to not make sense to me -- seems like your missing an || in there somewhere).

    this.ballCollide = function() {
    
        for (var i = 0; i < ball.length; i++) {
    
            var ax = ballX[i];
            var ay = ballY[i];
    
            for (var j = i + 1; j < ball.length; j++) {
    
                var bx = ballX[j];
                var by = ballY[j];
    
                var left    = ( ax <= bx + 50 );
                var right   = ( ax + 50 >= bx );
                var top     = ( ay + 50 >= by );
                var bottom  = ( ay <= by + 50 );
    
                if( (left && right) && (top && bottom) ){
    
                    movePosX[i] = -movePosX[i];
                    movePosY[i] = -movePosY[i];
                    movePosX[j] = -movePosX[j];
                    movePosY[j] = -movePosY[j];
    
                }
    
            }
        }
    }
    

    Here's a "contains" function which may prove useful:

    function contains (big, small){
    
        if( ! big || ! small ){
            return false;
        }
    
        var Oresult = {};
    
        var Obig    = {x:big.x,     y:big.y,    w:big.width,    h:big.height};
        var Osmall  = {x:small.x,   y:small.y,  w:small.width,  h:small.height};
    
        Obig.xMax   = Obig.x    + Obig.w;
        Obig.yMax   = Obig.y    + Obig.h;
    
        Osmall.xMax = Osmall.x  + Osmall.w;
        Osmall.yMax = Osmall.y  + Osmall.h;
    
        for (var p in Obig) {
    
            Oresult[p] = ( Obig[p] >= Osmall[p] ) ? true : false;
    
        }
    
        var retval = (!Oresult.x && !Oresult.y && Oresult.xMax && Oresult.yMax) ? true : false;
    
        return retval;
    }