How the snapping function was implemented
March 15th, 2006 in The Making of TheBroth · By David TapperOne of our goals was to allow players to position and align tiles with pixel-perfect-precision. We wanted to be able to automatically “snap” tiles to adjacent tiles, if the player opts to do so: If you hold down the shift key when you drop a tile near where you want it to go, it will automagically align next to the closest tile. No more squinting! This article describes how we implemented this functionality using JavaScript on the client side.

How does it work?
The code for the snapping is an algorithm built into the mouseUp handler - a function called mU(). It runs through a series of checks and calculations to work out where you actually want the tile to be.
Checking the for SHIFT key
The first task is to check whether the SHIFT key is down. This is determined by checking the shiftKey property of the event object. If it is true, then we know the player wants the tile to snap and the algorithm runs.
Here is a code fragment lifted straight from the mU() function:
if (window.event) e=window.event;
if (e.shiftKey) {
// we need to snap
Find the nearest tile
The next task is to find the tile that is nearest to the one you dropped. We loop through all the tiles checking their distance from the tile you just dropped. If no tile is within 1.5 tile widths, the algorithm assumes you don’t actually want to snap to a tile. (Why are you holding the shift key, dude?)
The method for finding the nearest tile includes some “if” statements. We check whether the tile is within 1.5 tile widths on the X and Y axis. For each tile that passes this test, we check it’s distance from the dragged tile using pythagoras’ famous square-on-the-hypotenuse equation:
distance = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
We run this equation for each tile that’s within close proximity (as defined by being not farther away than 1.5 tile widths). The tile with the smallest distance is the one we want to align with.
We could just run pythagoras’ equation for every tile and find the smallest distance. However, this would be CPU intensive, especially if there are many tiles that make up the mosaic; in our case, we have a 1000 tiles in each mosaic. The X and Y if statements narrow down the number of potential tiles without much demand on the CPU. The more expensive, but more accurate pythagoras equation is then run on a small number of nearby tiles.
Align the dropped tile
The next task is to find which edge of the stationary tile we want to align to.
There are eight possible positions: each of the four corners and four edges of the stationary tile. We use another set of if statements to find which edge is the nearest. If the tiles are aligned diagonally, then the dropped tile will snap to the nearest corner. Otherwise it will snap to the nearest edge.
Adjusting for the game area boundaries
Once we know where to snap the tile to, we have one last task. We need to make sure that the new, snapped-to position of the tile is not outside the game area. This is a simple check comparing the new position with the borders of the game area. If it is outside, then it is shifted in so that it meets the edge of the area.
Snap complete!
We now have a new snapped position for our tile. As the snapping happens on the client side, the snapped tile position will be sent to the server and on to all the other players in the next update cycle.












