I'll give you a kick start on converting between screen and map locations if you need it. If you assume your screen is the size of an entire map graphic (eg, width and height of the puzzle) and to scale, then to obtain the location on screen where an in-game coordinate is, you use. (NB: map.Cells.Width/.Height are 64 and 32).
Code:
public Point MapCoordinateToScreenPoint(Point mapCoordinate) {
return new Point(
(mapCoordinate.X - mapCoordinate.Y) * map.Cells.Height + (puzzle.Width / 2),
(mapCoordinate.X + mapCoordinate.Y - (map.Bounds.Height - 1)) * (map.Cells.Width / 2) + (puzzle.Height / 2)
);
}
Note that the point returned is actually outside the coordinate you want. The function returns a point which is the origin of a rectangle which surrounds the coordinate entirely (I'll refer to it as a "bounding rectangle" from here). Eg, in this image, the red dot is the location returned for each cell, so you would draw your tile relative to that location.
[Only registered and activated users can see links. Click Here To Register...]
Other way round, you want the coordinate for a given location on screen, it's a little trickier. You first want to find out which bounding rectangle that a given click was placed in. The bounding rectangles overlap eachother, so you need to eliminate those. To do this, we subtract x mod 64 and y mod 32 from the actual ordinates of of the click. (such that the results will always be an exact multiple of 64,32.)
Code:
Point blockOrigin = new Point(offset.X - (offset.X % map.Cells.Width), offset.Y - (offset.Y % map.Cells.Height));
You can then use this to determine the in-game coordinate which is bounded by the rectangle.
Code:
public Point ScreenPointToMapCoordinate(Point screenPoint) {
return new Point(
screenPoint.X / map.Cells.Width + screenPoint.Y / map.Cells.Height,
screenPoint.Y / map.Cells.Height + (puzzle.Width - screenPoint.X) / map.Cells.Width
);
}
The dilemma here is that you have only the bounding rectangle and it contains the corners of other in-game coordinates, so a click within that bounding rectangle could be a click on any of 5 different cells. To find out which cell the click was in, the easiest way is to use a "rainbow tile".
[Only registered and activated users can see links. Click Here To Register...]
You subtract the actual click location from the bounding rectangle location, leaving a value where x is between 0 and 63, y is between 0 and 31. (Performing mod 64/32 will do the same thing here). You then look up the color of the pixel at this point within the rainbow tile (you only need 1 of them), and based on one of 5 colors, you can determine the actual coordinate.
Code:
public class RainbowTile
{
private Bitmap bitmap;
public RainbowTile(Size cellSize)
{
bitmap = new Bitmap(cellSize.Width, cellSize.Height);
Point[] rainbowTrianglePoint1 = new Point[3] {
new Point(0, 0),
new Point(cellSize.Width / 2, 0),
new Point(0, cellSize.Height / 2),
};
Point[] rainbowTrianglePoint2 = new Point[3] {
new Point(cellSize.Width, 0),
new Point(cellSize.Width / 2, 0),
new Point(cellSize.Width, cellSize.Height / 2),
};
Point[] rainbowTrianglePoint3 = new Point[3] {
new Point(0, cellSize.Height / 2),
new Point(cellSize.Width / 2, cellSize.Height),
new Point(0, cellSize.Height),
};
Point[] rainbowTrianglePoint4 = new Point[3] {
new Point(cellSize.Width, cellSize.Height),
new Point(cellSize.Width / 2, cellSize.Height),
new Point(cellSize.Width, cellSize.Height / 2),
};
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
g.FillPolygon(Brushes.Green, rainbowTrianglePoint1);
g.FillPolygon(Brushes.Red, rainbowTrianglePoint2);
g.FillPolygon(Brushes.Blue, rainbowTrianglePoint3);
g.FillPolygon(Brushes.Yellow, rainbowTrianglePoint4);
g.Save();
}
public Point GetCell(Point coordinate, Point cellPoint)
{
Color col = _bitmap.GetPixel(Math.Max(0, cellPoint.X), Math.Max(0, cellPoint.Y));
if (col.R == 0 && col.G != 0 && col.B == 0)
coordinate.X--;
else if (col.R != 0 && col.G == 0 && col.B == 0)
coordinate.Y--;
else if (col.R == 0 && col.G == 0 && col.B != 0)
coordinate.Y++;
else if (col.R != 0 && col.G >= 0 && col.B == 0)
coordinate.X++;
return coordinate;
}
}
The rainbow tile is there to make it easier to understand, but a simple array of 64x32 would suffice.