Hello everyone. I'm currently in the process of writing a level editor in C# for a 2d game I've been writing in XNA, and I've hit a small snag.
Essentially, I load an image into the picturebox. The image itself it a tilesheet of the tiles used in a level, all squares. I then draw a grid overtop the image to separate the files. This all works fine.
The problem is, when I click on a tile to select it, I need to draw a rectangle around the selected tile. This also works fine, however when I click a new tile the old rectangle does not clear. Basically if I keep clicking new tiles they will all eventually look like they are selected.
I'm having a problem conceptualizing a solution. How can I totally invalidate the image when I click the picture box, redraw the original image, then redraw the grid, without having the leftover selection recticle?
Here are the functions being used.
| private void LoadTexture(string fileName) |
| { |
| Cursor = Cursors.WaitCursor; |
| |
| string buildError; |
| |
| // im storing the actual image here in a member field |
| tilesImage = Image.FromFile(fileName); |
| |
| tilesBox.Image = tilesImage; |
| |
| mapTiles = LoadContent<Texture2D>(fileName, null, null, out buildError); |
| |
| map.SetTileTexture(mapTiles); |
| map.Initialize(); |
| |
| tilesetXCount = (int)(tilesImage.Width / tileSize); |
| tilesetYCount = (int)(tilesImage.Height / tileSize); |
| |
| Cursor = Cursors.Arrow; |
| } |
| |
| |
| private void tilesBox_Paint(object sender, EventArgs e) |
| { |
| DrawGrid(); |
| DrawSelection(); |
| } |
| |
| private void tilesBox_Click(object sender, EventArgs e) |
| { |
| tilesBox.Invalidate(); |
| |
| int mx = Mouse.GetState().X; |
| int my = Mouse.GetState().Y; |
| |
| Vector2 mouseTileLocation = new Vector2((float)(mx / tileSize), (float)(my / tileSize)); |
| |
| // set selected tile |
| selectedTile.Position = mouseTileLocation; |
| selectedTile.SourceRect = new Microsoft.Xna.Framework.Rectangle( |
| (int)mouseTileLocation.X * tileSize, |
| (int)mouseTileLocation.Y * tileSize, |
| tileSize, |
| tileSize |
| ); |
| selectedTile.ID = (int)((mouseTileLocation.Y * tilesetXCount) + mouseTileLocation.X) + 1; |
| } |
| |
| |
| public void DrawSelection() |
| { |
| if ((tilesBox.Image != null)) |
| { |
| // as we cannot convert from an XNA rect to a GDI rect, use the |
| // values directly |
| |
| graphics.DrawRectangle(selectedPen, |
| selectedTile.SourceRect.X, |
| selectedTile.SourceRect.Y, |
| selectedTile.SourceRect.Width, |
| selectedTile.SourceRect.Height); |
| } |
| } |
| |
| /// <summary> |
| /// Draw a grid over the tile texture |
| /// </summary> |
| public void DrawGrid() |
| { |
| if (tilesBox.Image != null) |
| { |
| graphics = Graphics.FromImage(tilesBox.Image); |
| |
| for (int y = 0; y < tilesBox.Image.Height / tileSize; y++) |
| { |
| for (int x = 0; x < tilesBox.Image.Width / tileSize; x++) |
| { |
| graphics.DrawLine(gridPen, x * tileSize, 0, x * tileSize, tilesBox.Image.Height); |
| } |
| graphics.DrawLine(gridPen, 0, y * tileSize, tilesBox.Image.Width, y * tileSize); |
| } |
| } |
| } |
| |