public static int GetNumberOfTilesWide(int imageWidth, int margin, int tileWidth, int spacing)
{
if (tileWidth == 0)
{
throw new Exception("The tileWidth must not be 0");
}
// The following logic
// deserves an explanation:
// Consider a simple tileset
// with 2 tiles, and a single
// spacing between them. Assume
// that the tiles are 16 pixels wide
// and that the spacing is 1 pixel wide.
// In this case, the width of the entire
// tileset image would be 33. That's (16+1+16).
// However, let's look at the following line of code
// below:
//int tilesWide = (imageWidth - margin) / (tileWidth + spacing);
// In this case, the formula would be:
// int tilesWide = (33-0) / (16+1);
// Which is equivalent to:
// int tilesWide = 33 / 17;
// which is equivalent to:
// int tilesWide = 1;
// But we clearly stated above that we have two tiles (16+1+16).
// The reason for this is because each tile *except the last* will
// be considered to be wider by 1 because of its spacing value. The
// last one won't be considered wider because there's always one-less space
// than there are tiles.
// We can correct this simply by adding 1 to the resulting tilesWide *if* there
// is spacing...
// Update January 26, 2014
// We need to multiply margin
// by 2 since the margin applies
// to all sides
// ...so let's do that here:
//int tilesWide = (imageWidth - (2 * margin)) / (tileWidth + spacing);
//if (spacing != 0)
//{
// tilesWide++;
//}
// Update February 7, 2014
// No, this doesn't seem like it's working right, and it's confusing, so I'm going
// to break this down a bit:
// First let's take off the margin so we can see how
// much usable space we have:
int usableSpace = imageWidth - 2 * margin;
// If there is a margin, all tiles except the last will have the margin added to the right of them
// Since the last one won't have the margin added, let's just add the margin to the usable space, then do
// a simple int division:
usableSpace += spacing;
return usableSpace / (tileWidth + spacing);
}