Search code examples
htmlcanvascollision-detectionkineticjs

Collision detection of 2 gifs on canvas


I have several images already loaded on a canvas and i want to add simple collision detection (when any of them collide, show a message or change the color, etc). I'm loading the images by way of:

// Taurus Image
    var taurusImg = new Kinetic.Image({
      x: 0,
      y: 0,
      image: images.Taurus,
      width: 216,
      height: 75,
      name: 'image'
    });

    taurusGroup.add(taurusImg);

    taurusGroup.on('dragstart', function() {
      this.moveToTop();
    });

    // Truck Image
    var truckImg = new Kinetic.Image({
      x: 0,
      y: 0,
      image: images.Truck,
      width: 950,
      height: 158,
      name: 'image'
    });

    truckGroup.add(truckImg);

    truckGroup.on('dragstart', function() {
      this.moveToTop();
    });

And i'm loading them in the sources:

var sources = {

    Taurus: 'content/taurus.gif',
    Truck: 'content/truck2.gif'
  };

after calling a function loadimages i thought i could use something like this:

function collides(a, b)
    {
        if (a.x < b.x + b.width &&
            a.x + a.width > b.x &&
            a.y < b.y + b.height &&
            a.y + a.height > b.y) return true;
    }

But nothings happening. Do i need to load the images another way? As i said they are all on the screen already and i'm able to drag them around i just can't get collision detection working. Thank you so much for any help/advice you guys might have!!


Solution

  • A couple possible issues here:

    1. Your collides function isn't referencing the correct object properties

    If you're passing the Kinetic objects themselves, you'll want to use the accessor methods:

    function rectanglesOverlap(r1, r2) {
      return (r1.x() < r2.x() + r2.width() &&
        r1.x() + r1.width() > r2.x() &&
        r1.y() < r2.y() + r2.height() &&
        r1.y() + r1.height() > r2.y());
    }
    

    2. Are you running your collision detection?

    layer.find('.image').on('dragmove', function() {
      detectCollisions();
    });
    
    function detectCollisions() {
      var images = layer.find('.image');
      images.stroke(null);
    
      for (var i=0; i<images.length; i++) {
        for (var j=i+1; j<images.length; j++) {
          if ( rectanglesOverlap(images[i], images[j]) ) {
            images[i].stroke('red');
            images[j].stroke('red');
          }
        }
      }
    }
    

    Here's a fiddle demonstrating collision detection (it substitutes rectangles for your images):

    http://jsfiddle.net/klenwell/z6zTA/