Friday, July 25, 2014

(On this blog I'll sometimes go into the “making of” the game programming tutorials I post on my site.)

For my pathfinding pages I wanted to support "painting" on the map to make or erase walls. When you change the map, the pathfinding algorithm updates the paths. Here's how paint works:

Set up mousedown, mousemove, mouseup event handlers on all the tiles.

  1. When you press the mouse button, I toggle the tile you're pointing to.
  2. When you move the mouse, I set the tiles you pass over to match the tile you first clicked on.
  3. When you release the mouse, I stop tracking the mouse.

For example, if there are three tiles A B C and you are over A without a wall, then press the mouse button, I put a wall at A (toggle). If you then move the mouse over B, I make B a wall (set to whatever A has). And then if you release the mouse over C, I'll set C to a wall as well.

When I first published the Introduction to A* article two weeks ago, I still had an item on my bug list to fix map editing on a touch screen. I wasn't sure why it wasn't working. I figured the touch events touchstart, touchmove, touchend would map cleanly to mousedown, mousemove, mouseup. But they didn't. After some debugging, I figured out that the touchmove and touchend events get sent to the object that received the touchstart event. That means instead of seeing A.mousedown, A.mousemove, B.mousemove, C.mousemove, C.mouseup, I am seeing A.touchstart, A.touchmove, A.touchend. I don't receive events on B or C at all.

To fix this, for touch events I look up the x,y position of the touch and map that back onto a tile. This is sort of annoying, as I figure browsers already have a way to map pixel locations to SVG DOM objects, but I don't know how to harness that lookup. Fortunately, most of the diagrams are simple square grids, so the code to map pixels to grid locations is easy.

There are some more tweaks for the page to work well on touch screens, but it should mostly work now.