HTML5 Game - Using Pixel Data to Detect Object Collisions

Introduction

We can use the context.getImageData() to check pixel-level collision.

Demo

ResultView the demo in separate window

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);  
function eventWindowLoaded() {//  w ww  .  j  a  v  a  2 s  .  c o  m
  canvasApp();

}


function canvasApp(){
  

      let theCanvas = document.getElementById('canvas');
      let context = theCanvas.getContext('2d');
  
  let blueObject={};
  let redObject={};
  
  blueObject.x=0;
  blueObject.y=200;
  blueObject.dx=2;
  blueObject.width=48;
  blueObject.height=48;
  blueObject.image=new Image();
  blueObject.image.src="http://java2s.com/style/download.png";
  
  context.drawImage(blueObject.image, 0, 0);
  blueObject.blueImageData=context.getImageData(0, 0, blueObject.width, blueObject.height);
  context.clearRect(0,0,theCanvas.width, theCanvas.height);
  
  redObject.x=348;
  redObject.y=200;
  redObject.dx=-2;
  redObject.width=48;
  redObject.height=48;
  redObject.image=new Image();
  redObject.image.src="http://java2s.com/style/demo/jet.png";
  
  context.drawImage(redObject.image, 0, 0);
  redObject.redImageData=context.getImageData(0, 0, redObject.width, redObject.height);
  context.clearRect(0,0,theCanvas.width, theCanvas.height);
  
  function drawScreen() {
    blueObject.x+=blueObject.dx;
    redObject.x+=redObject.dx;
  
    context.clearRect(0,0,theCanvas.width, theCanvas.height);
    context.drawImage(blueObject.image, blueObject.x, blueObject.y);
    context.drawImage(redObject.image, redObject.x, redObject.y);
    
    console.log("redObject.redImageData.data[3]=" + redObject.redImageData.data[3]);
    if (boundingBoxCollide(blueObject, redObject)){
      console.log("bounding box collide");
      
      let xMin = Math.max( blueObject.x, redObject.x );
      let yMin = Math.max( blueObject.y, redObject.y );
      let xMax = Math.min( blueObject.x+blueObject.width, redObject.x+redObject.width );
      let yMax = Math.min( blueObject.y+blueObject.height, redObject.y+redObject.height );
      
      
      for ( let pixelX = xMin; pixelX < xMax; pixelX++ ) {
        for ( let pixelY = yMin; pixelY < yMax; pixelY++ ) {
          let bluepixel = ((pixelX-blueObject.x ) + (pixelY-blueObject.y )*blueObject.width )*4 + 3 ;
          let redpixel = ((pixelX-redObject.x) + (pixelY-redObject.y)*redObject.width)*4 + 3 ;
          
          if (( blueObject.blueImageData.data [ bluepixel ] !== 0 ) &&( redObject.redImageData.data[ redpixel ] !== 0 )) {
            console.log("pixel collision")
            blueObject.dx=0;
            redObject.dx=0;
            break;
          }
        }
      }
    }
  }
  function boundingBoxCollide(object1, object2) {
    let left1 = object1.x;
    let left2 = object2.x;
    let right1 = object1.x + object1.width;
    let right2 = object2.x + object2.width;
    let top1 = object1.y;
    let top2 = object2.y;
    let bottom1 = object1.y + object1.height;
    let bottom2 = object2.y + object2.height;
      
    if (bottom1 < top2) return(false);
    if (top1 > bottom2) return(false);
      
    if (right1 < left2) return(false);
    if (left1 > right2) return(false);
      
    return(true);

  };
  
  function startUp(){
    gameLoop();
  }
   
  function gameLoop() {
    window.setTimeout(gameLoop, 100);
    drawScreen();    
  }
  
  startUp();
  
}


</script> 
</head>
<body>
<div>
<canvas id="canvas" width="400" height="400"  style="position: absolute; top: 50px; left: 50px;">
 Your browser does not support the HTML 5 Canvas. 
</canvas>


</div>


</body>
</html>

Related Topic