Search code examples
javascriptjquerycollision-detectioncollision

Results of collision happening before collision actually occurs


After getting advice to use this "style" of collision detection instead of jQuery Collision -

function isCollide(a, b) {
    return !(
        ((a.y + a.height) < (b.y)) ||
        (a.y > (b.y + b.height)) ||
        ((a.x + a.width) < b.x) ||
        (a.x > (b.x + b.width))
    );
}

I am trying it but am having an issue: the "else" part that is suppose to happen when the collision occurs is happening instantaneously for some reason, as soon as the page is loaded.

Here is the Fiddle.

And here is the function:

function homePage() {

    //initial animation
    for (var i=0; i<links.length; i++) {
        //animate links
        $(links[i]).animate({
            top: '0'
        }, {
            duration: 2000*(Math.random()*(1.1)+1), 
            easing: 'easeOutBounce',
            step: function() {

                if ($(links[i]).x > ($(".footer").x + $(".footer").width) 
                || $(links[i]).y > ($(".footer").y + $(".footer").height) 
                || ($(links[i]).x + $(links[i]).width) < $(".footer").x 
                || ($(links[i]).y + $(links[i]).height) < $(".footer").y)
                {
                    $(links[i]).css("background-color", "yellow");
                } 
                else 
                {
                    $(links[i]).css("background-color", "red");
                }
            }
        })
    }
}

Solution

  • I saw these mistakes:

    1. When the step function is called, i equals links.length. Read How do JavaScript closures work? to understand more about this error. An easy solution is to use Array.forEach (or $.each): FIDDLE

      links.forEach(function(linkId){
          var $link = $(linkId);
          //...
      });
      
    2. There are no .x nor .y on a jquery object, use .offset().left and .offset().top instead: FIDDLE

      if ($link.offset().left > ($(".footer").offset().left + $(".footer").width) //...
      
    3. On a jquery object, width and height are functions: FIDDLE

      if ($link.offset().left > ($(".footer").offset().left + $(".footer").width()) //...
      

    That should be enough to fix your code. Also try to use more variables, that will clean your code and help you find bugs.


    These three mistakes were making the condition to always equal false:

    1. i was equal to links.length, so links[i] was undefined and $(links[i]) was an empty jQuery object. You can't find the position and the size of an empty jQuery object (and that's not what you want, you want the position and the size of the DIV)
    2. $link.x and $link.y are undefined, so you're comparing undefined values where you want to compare position values.
    3. .width and .height are functions, not the real size. Again, you're comparing streange meaningless values instead of comparing the bottom-right position values.