Next page | Contents page |

Hitting a target

Many games involve pointing to particular shapes (perhaps to shoot at them). So we need to be able define target areas in the canvas and check whether a mouse point lies within any of them. The simplest shape would be a rectangle, perhaps defined as {x:xLeft, y:yTop, w:width, h:height}. An array of such rectangles could be held in our global object as DATA.shapes. Then a simple way to check whether mouse point pt is within any of them would be:


	for (let i = 0; i < DATA.shapes.length; i++)
	{
	  let ti = DATA.shapes[i];
	  if (pt.x >= ti.x && pt.x <= ti.x + ti.w
	   && pt.y >= ti.y && pt.y <= ti.y + ti.h)
	  {
	    return i;
	  }
	}
	return -1; // meaning not found
Notice the double && meaning logical AND. A single & would mean something quite different and would cause an error. Similarly logical OR is ||. Also notice the signs for greater-than-or-equal-to and less-than-or-equal-to.

Shapes may have more complicated outlines, such as circles or polygonal paths. For this the graphics context has a method isPointInPath() and you can read about it on MDN.

Javascript is a very flexible language compared to some others (a bit too flexible for beginners, I suspect). One of the nice aspects is that an array can contain different types of things in each of its elements. So DATA.shapes can contain many different shapes. I would make a literal object for each kind of shape, including a text string saying which kind it is. Examples:


	DATA.shapes[0] = 
	  {kind:"rect", x:10, y:10, w:100, h:40, fill:"red", stroke:"blue"};
	DATA.shapes[1] = 
	  {kind:"path", path:[pt1, pt2, pt3], fill:"", stroke:"green"};

Then when drawing or testing for hits I would use a switch statement (see MDN):


	let si = DATA.shapes[i];
	switch (si.kind)
	{
	  case "rect": // draw or test using si.x, si.y, si.w, si.d
	               break;
	  case "path": // draw or test using si.path array
	               break;
	  // and others, such as "circle"
	}
Next page | Contents page |