Поделиться через


Detecting collisions in a 2D HTML5 game

Many games need to determine when one game object has collide into another. This topic discusses Boulder Bop's collision detection.

There are two core object types used in Boulder Bop: SVG images and SVG circles.

SVG Images

To detect if an SVG circle has collided with an SVG image, we check if the circle's center is "close enough" to the image's center. here's an example used to detect if a boulder (SVG circle) has collided with a bunker (SVG image):

if ( Math.abs(boulderX - bunkerCenterX) < TARGET_SENSITIVITY && Math.abs(boulderY - bunkerCenterY) < TARGET_SENSITIVITY) {
  _objects[i].markActive(false); // Mark the boulder object as inactive so that exited() returns true on it in the main game loop (i.e., in update()).
    .
    .
    . 
  _objects.push(BunkerExplosion(bunkerExplosionSpec));
}

If a boulder is close enough to a bunker (as determined by TARGET_SENSITIVITY), the bunker is marked for destruction using _objects[i].markActive(false). This, ultimately, removes the bunker object from _objects[]. Also, when a boulder has collided with a bunker, we "replace" it with a bunker explosion by calling the BunkerExplosion constructor and putting its returned object into _objects[].

Note  As an aside, be aware that SVG images (<image>) are different than HTML images (<img>).

 

SVG Circles

To detect if two SVG circles have collided, such as a missile or boulder, check the distance between the two circles to see if it's less than or equal to the sum of their radii:

var circlesOverlap = function(circleA, circleB) { // Public. Returns true if the SVG circles A and B overlap, false otherwise.
  var deltaX = circleA.cx.baseVal.value - circleB.cx.baseVal.value;
  var deltaY = circleA.cy.baseVal.value - circleB.cy.baseVal.value;
  var distance = Math.sqrt( (deltaX*deltaX) + (deltaY*deltaY) ); // The classic distance-between-two-points formula.
  var radiusA = circleA.r.baseVal.value; // The radius of circle A.
  var radiusB = circleB.r.baseVal.value; // The radius of circle B.
        
  if (circleA.id == circleB.id) // If true, circleA and circleB are the same circle.
    return false;
  
  return distance <= (radiusA + radiusB);
}; // circlesOverlap()
      
that.circlesOverlap = circlesOverlap;

Next in the Boulder Bop series, we move onto Touch input for an HTML5 game.