36

I'm just developing a simple balloon game with two divs. The problem is that I'm unable to trigger a function when the two divs touch each other.

Saravanan
  • 363
  • 1
  • 14
sudheer
  • 371
  • 1
  • 3
  • 3
  • So the divs are moving? Or what exactly is happening and what are you trying to cause? – justkt Mar 24 '11 at 12:34
  • Are you using jQuery draggables or anything? This question needs more information / clarification in order to get a response. – Tejs Mar 24 '11 at 12:34
  • Please provide more info and some code. – Ant Mar 24 '11 at 12:36
  • 1
    Was this really worth a downvote? Its a relevant, clear question even if example code would make it better. And a new user no less. – Matt Mar 24 '11 at 12:43
  • This question might also be relevant: http://stackoverflow.com/questions/8628368/how-do-i-implement-collision-detection-between-a-set-of-div-elements – Anderson Green Dec 29 '12 at 05:27

4 Answers4

60

You're looking for bounding box collision detection. If you want to raise an event, you have to repeatedly test, but it would be better just to run the function over all your game objects from your game loop. The sandbox is at http://jsfiddle.net/nGRwt/7/

  function collision($div1, $div2) {
      var x1 = $div1.offset().left;
      var y1 = $div1.offset().top;
      var h1 = $div1.outerHeight(true);
      var w1 = $div1.outerWidth(true);
      var b1 = y1 + h1;
      var r1 = x1 + w1;
      var x2 = $div2.offset().left;
      var y2 = $div2.offset().top;
      var h2 = $div2.outerHeight(true);
      var w2 = $div2.outerWidth(true);
      var b2 = y2 + h2;
      var r2 = x2 + w2;

      if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
      return true;
    }
Victor S
  • 5,098
  • 5
  • 44
  • 62
BC.
  • 24,298
  • 12
  • 47
  • 62
11

You can try jquery-collision plus jquery-ui-draggable-collision. Full disclosure: I just wrote and released these on sourceforge.

The first allows this:

var hit_list = $("#collider").collision(".obstacle");

which is the list of all ".obstacle" that overlap "#collider".

The second allows:

$("#collider").draggable( { obstacle: ".obstacle" } );

Which gives you (among other things), a "collision" event to bind to:

$("#collider").bind( "collision", function(event,ui){...} );

And you can even set:

$("#collider").draggable( { obstacle: ".obstacle", preventCollision: true } );

to prevent "#collider" from ever overlapping any ".obstacle" while dragging.

eruciform
  • 7,680
  • 1
  • 35
  • 47
3

in Native Javascript

var is_colliding = function(div1, div2) {
  var d1_height = div1.offsetHeight;
  var d1_width = div1.offsetWidth;
  var d1_distance_from_top = div1.offsetTop + d1_height;
  var d1_distance_from_left = div1.offsetLeft + d1_width;

  var d2_height = div2.offsetHeight;
  var d2_width = div2.offsetWidth;
  var d2_distance_from_top = div2.offsetTop + d2_height;
  var d2_distance_from_left = div2.offsetLeft + d2_width;

  var not_colliding =
    d1_distance_from_top < div2.offsetTop ||
    div1.offsetTop > d2_distance_from_top ||
    d1_distance_from_left < div2.offsetTop ||
    div1.offsetLeft > d2_distance_from_left;

  return !not_colliding;
};
Gaurav Mogha
  • 370
  • 3
  • 9
2

The answer from Victor S above was useful but I needed to check whether two divs overlapped completely, i.e. eclipsed (but this was hard to google for since results were polluted with references to the Eclipse IDE).

Sharing my modified version in case anyone finds it useful:

$(function() {
  /**
   * Function to determine whether the first element completely 
   *  eclipses the second element
   */
  function collision($div2, $div1) {
    var x1 = $div1.offset().left;
    var y1 = $div1.offset().top;
    var h1 = $div1.outerHeight(true);
    var w1 = $div1.outerWidth(true);
    var b1 = y1 + h1;
    var r1 = x1 + w1;
    var x2 = $div2.offset().left;
    var y2 = $div2.offset().top;
    var h2 = $div2.outerHeight(true);
    var w2 = $div2.outerWidth(true);
    var b2 = y2 + h2;
    var r2 = x2 + w2;

    return x1 > x2 && y1 > y2 && b1 < b2 && r1 < r2
      ? true
      : false
  }

  // draggable jQuery listener required jQuery UI
  // Just used to illustrate the above
  $('#div1,#div2').draggable({
    drag: function() {
      if (collision($('#div1'), $('#div2'))) {
        $('#div2').text('Eclipsing').css({'background-color': 'grey'})
      } else {
        $('#div2').text('Not eclipsing').css({'background-color': 'green'})
      }

      $('#result').text(collision($('#div1'), $('#div2')));

    }
  });
});
.box {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

#div1 {
  width: 200px;
  height: 200px;
  background-color: pink;
}
#div2 {
  width: 75px;
  height: 75px;
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>

<strong>Drag divs around.</strong>
<p>Eclipsing? <span id="result">false</span>

<div id="wrapper">
  <div id="div1" class="box">
    Div1
  </div><br/>
  <div id="div2" class="box">
    Not eclipsing
  </div>
</div>