The time has come to write the most important function in the context of our application, namely the function responsible for detecting collisions.

6. Function checking for collisions

Every <div> is actually a rectangle and has four sides, therefore, we should take care of four basic conditions checking whether a collision has occurred.

Let’s think about the data that we already have. For sure, these are going to be the coordinates of all the corners of the movingObj object, i.e.:

top left: movingObj.posXmin, movingObj.posYmin,
bottom left: movingObj.posXmin, movingObj.posYmax,
top right: movingObj.posXmax, movingObj.posYmin,
bottom right: movingObj.posXmax, movingObj.posYmax.

Moreover, we also have identical information characterising the position of the static objects. Let’s describe the static blocks within the function checking for collisions (let’s call it collisionsDetection) in the form of local variables:

/* Collisions - moving object vs static elements */ 
function collisionsDetection(obj) { 
    var posXmin = obj.posXmin; 
    var posXmax = obj.posXmax; 
    var posYmin = obj.posYmin; 
    var posYmax = obj.posYmax;
}

The “obj” argument is actually a static object, so it is basically every object stored in the array staticObjArray created in the previous step.

Now, let’s move on to the conditions checking for collisions. As an example, we’ll take a closer look at the left side of a static <div> and the corresponding right side of an object in motion (if the object moves from left to right, only its right side is prone to collisions, which is quite logical). Theoretically we can assume that if the width of the object was speed = 1, a collision would occur at the moment when movingObj.posXmax = posXmin, under the following conditions:

(movingObj.posYmin <= posYmax) && (movingObj.posYmax >= posYmin)

It could seem that the problem of collisions has just been solved for the right side of the movingObj object – however, you couldn’t be further from the truth. Let’s assume that the speed of the object was increased from one pixel to eight. And what happens now? MovingObj will move across a surface in 8-pixel intervals, so the probability that in one of subsequent iterations the movingObj.posXmax value will be exactly the same (no more and no less) as the posXmin of the static object is very low – most likely the movingObj.posXmax will take a value higher or lower than posXmin. How to solve that problem? Well, it’s very easy. We just need to enter the area prone to collisions, instead of a side of an object. Like that:

/* Left side of object */
if (
    (movingObj.posXmax + speed > posXmin) &&
    (movingObj.posXmax <= posXmin) &&
    (movingObj.posYmin <= posYmax) &&
    (movingObj.posYmax >= posYmin)
) 
{
…
}

Take a look at the image with a graphic presentation of the above set of conditions.

collistion of two divs

The black square represents a static block, the grey square – our object moving from left to right, and the red rectangle – the area prone to collisions. Increasing the movingObj.posXmax coordinate by speed will make us move one iteration too far, thus creating a „virtual” space between the object in motion and the static one. If the function detects that in the next iteration a static object will be placed within this space, a collision occurs.

Now, let’s move on to describing events caused at the moment when the objects come into contact. We can implement any event at the time of collision. In our case it should be the following:

movingObj.posXmin = posXmin - movingObj.cssWidth; 
movingObj.isMovingRight = false;

As a result, a movable object will adhere to the static one at the moment of collision and at the same time the possibility of movement will be blocked as a consequence of movingObj.isMovingRight = false.

Below, I’ve provided the body of the function responsible for collisions “on all sides”:

/* Collisions - moving object vs static elements */ 
function collisionsDetection(obj) { 
    var posXmin = obj.posXmin; 
    var posXmax = obj.posXmax; 
    var posYmin = obj.posYmin; 
    var posYmax = obj.posYmax;
    / * Left side of object */ 
    if ( 
        (movingObj.posXmax + speed > posXmin) && 
        (movingObj.posXmax <= posXmin) && 
        (movingObj.posYmin <= posYmax) && 
        (movingObj.posYmax >= posYmin) 
        ) 
    { 
        movingObj.posXmin = posXmin - movingObj.cssWidth; 
        movingObj.isMovingRight = false; 
    }
    /* Right side of object */ 
    if ( 
        (movingObj.posXmin - speed < posXmax) && 
        (movingObj.posXmin >= posXmax) && 
        (movingObj.posYmin <= posYmax) && 
        (movingObj.posYmax >= posYmin) 
        ) 
    { 
        movingObj.posXmin = posXmax; 
        movingObj.isMovingLeft = false; 
    }
    /* Up side of object */ 
    if ( 
        (movingObj.posYmax + speed > posYmin) && 
        (movingObj.posYmax <= posYmin) && 
        (movingObj.posXmin < posXmax) && 
        (movingObj.posXmax > posXmin) 
        ) 
    { 
        movingObj.posYmin = posYmin - movingObj.cssHeight; 
        movingObj.isMovingDown = false; 
    } 
    /* Down side of object */ 
    if ( 
        (movingObj.posYmin - speed < posYmax) && 
        (movingObj.posYmin >= posYmax) && 
        (movingObj.posXmin < posXmax) && 
        (movingObj.posXmax > posXmin) 
        ) 
    { 
        movingObj.posYmin = posYmax; 
        movingObj.isMovingTop = false; 
    } 
};

It wasn’t so difficult after all, was it?

7. Initialization of the main control loop

Finally, the only thing left to do is initiating the main loop. In order to do that, we’ll write three functions responsible for the following functionalities respectively:

checking for collisions for all static elements;
“packing” and calling all functions that are repeatable in the subsequent iterations, i.e. a function checking for collisions for all static elements and a draw() function refreshing the position of an object in motion;
initiating the main control loop.

Here are their implementations:

/* Check collisions for all objects */ 
function detectCollisions() { 
    for (index in staticObjArray) { 
        collisionsDetection(staticObjArray[index]); 
    } 
}
/* There are stored all actions which have to be checked in each iteration of main loop */ 
function setRepetitiveActions() { 
    detectCollisions(); 
    movingObj.draw(); 
} 
/* Define the main loop */ 
function setrequestAnimationFrame() { 
    setRepetitiveActions(); 
    requestAnimationFrame(setrequestAnimationFrame); 
}

Now, let’s initiate the main loop in order to bring our application into life:

/* Start - initiate the main loop */
setrequestAnimationFrame();

Voilà! Everything works the way it should.

Below you can find a file pack to be downloaded.

collisions.zip