8

I'm creating a game in Javascript. currently the sprites are div elements with a background image that is updated to create animation. I have heard that if I make the elements canvas and blit the sprite onto the canvas I can make the sprite clickable, omitting the transparent areas.

I need a solution where my game sprites can be clicked but the clickable area is fitted to the shape of the sprite. It also needs the be automatic. I cannot do this with pre-made click maps.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Robert Hurst
  • 8,902
  • 5
  • 42
  • 66

2 Answers2

8

I have a tutorial that does almost exactly what you need for the hit-testing. See the code here.

When you click, the code draws each shape (I use rectangles but it works beautifully with semi-transparent images) to a canvas in memory (ghostcanvas) and checks to see if the mouse pixel is on a pixel that is not-transparent.

Relevant code pasted below:

function myDown(e){
  getMouse(e);
  clear(gctx); // clear the ghost canvas from its last use

  // run through all the boxes
  var l = boxes.length;
  for (var i = l-1; i >= 0; i--) {
    // draw shape onto ghost context
    drawshape(gctx, boxes[i], 'black');

    // get image data at the mouse x,y pixel
    var imageData = gctx.getImageData(mx, my, 1, 1);
    var index = (mx + my * imageData.width) * 4;

    // if the mouse pixel exists, select and break
    if (imageData.data[3] > 0) {
      mySel = boxes[i];
      offsetx = mx - mySel.x;
      offsety = my - mySel.y;
      mySel.x = mx - offsetx;
      mySel.y = my - offsety;
      isDrag = true;
      canvas.onmousemove = myMove;
      invalidate();
      clear(gctx);
      return;
    }

  }
  // havent returned means we have selected nothing
  mySel = null;
  // clear the ghost canvas for next time
  clear(gctx);
  // invalidate because we might need the selection border to disappear
  invalidate();
}
Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • I have tried your code with images. Its not working with images. Somehow the images are not drawn on ghost canvas. You can check code here. I want to make images draggable. Can you plz fix the problem http://jsfiddle.net/V8NPF/8/ – Gohel Kiran Oct 21 '12 at 16:34
6

You could have the background be transparent and check images for transparency at the clicked pixel. Here's some code from one of my game prototypes:

function getAlphaInImage(img, x, y) {
    var tmp = document.createElement("CANVAS");
    tmp.setAttribute('width', img.width);
    tmp.setAttribute('height', img.height);
    var tmpCtx = tmp.getContext('2d');
    tmpCtx.drawImage(img, 0, 0);
    var imageData = tmpCtx.getImageData(x, y, 1, 1);
    var alpha = imageData.data[3];
    tmp = null;
    imageData = null;
    return alpha;
}

Before calling this I first check if the mouseclick was within the whole image.

Bemmu
  • 17,849
  • 16
  • 76
  • 93
  • 1
    That's the approach I would take, too, except that it would be more efficient to create the canvas once and cache it, rather than doing all this work on each click. – alekop May 10 '11 at 21:18
  • 1
    On the other hand you will probably never have more than one click per frame and in a typical game only very few images to check against. Personally I would just do it like this and then optimize later if it turns out to be too slow. – Bemmu May 10 '11 at 22:53