
The TileEditor control edits a grid of tiles. It can be used to quickly create fast editors of tile based games. It supports 2D grids with multiple layers, and can paint relatively fast using GDI.
The current version supports editing of small and medium maps, mutliple selections of tiles, copy and pasting of tiles and multiple undo and redo actions.
Frequently, I have needed a Tile Editing control so I can quickly make editors to edit maps for Tile Based games. None were around at the time, so I decided to create my own. The control is a quick painting tile editor, letting you create editors of many kinds quickly and easily.
The TileEditor control can be used like any other control. The map and tile sizes are simple properties which you can change in design time and runtime. To add spacing between the tiles, you can set the TileSpacing property to the number of pixels you want between the tiles. To draw the tiles, there is an event called PaintTile which is passed a TileEventArgs instance which contains the location of the tile that is being drawn and the PaintEventArgs instance. You can then paint anything you like; the following example is from the demo which paints the tile image inverted if selected or normally if not selected.
private void TileEditor_PaintTile(object sender, TileEventArgs e)
{
int tile = TileEditor[e.Location];
Bitmap b = (Bitmap)GetTileImage(tile).Clone();
if (e.Selected) {
e.PaintArgs.Graphics.DrawImage(TileEditor.InvertBitmap(b),
e.PaintArgs.ClipRectangle, new Rectangle(0, 0, 32, 32), GraphicsUnit.Pixel);
} else {
e.PaintArgs.Graphics.DrawImage(b,
e.PaintArgs.ClipRectangle, new Rectangle(0, 0, 32, 32), GraphicsUnit.Pixel);
}
}
To edit the map, you will need to add the MouseDown event. This is passed the MouseTileEventArgs instance, which includes the location of the tile that was clicked. You can add code to change the tile in any way; in the demo, there are two selected tiles (one for the left mouse click and one for the right). If shift is held down, it will edit the bottom layer instead of the top layer. For continuous editing when dragging, you will need to do the same code in the MouseMove event. To make it more efficient, you can record the last tile the mouse is on, and only edit the tile if the last tile is different from the current tile. An example is as follows:
private void TileEditor_MouseDown(object sender, MouseTileEventArgs e)
{
TilePoint pt = e.Location;
if (ShiftDown)
pt.Z = 0;
else
pt.Z = 1;
if (e.MouseArgs.Button == MouseButtons.Left)
TileEditor.SetTile(pt, LeftTile);
else if (e.MouseArgs.Button == MouseButtons.Right)
TileEditor.SetTile(pt, RightTile);
}
TilePoint LastMouse;
private void TileEditor_MouseMove(object sender, MouseTileEventArgs e)
{
TilePoint pt = e.Location;
if (ShiftDown)
pt.Z = 0;
else
pt.Z = 1;
if (pt != LastMouse) {
if (e.MouseArgs.Button == MouseButtons.Left) {
TileEditor.SetTile(pt, LeftTile);
} else if (e.MouseArgs.Button == MouseButtons.Right) {
TileEditor.SetTile(pt, RightTile);
}
LastMouse = pt;
RefreshSelectedTiles();
}
}
bool ShiftDown;
private void Editor_KeyDown(object sender, KeyEventArgs e)
{
if (e.Shift)
ShiftDown = true;
}
private void Editor_KeyUp(object sender, KeyEventArgs e)
{
ShiftDown = false;
}

Zoom levels can easily be done by just changing the tile size. When drawing in the PaintTile event, it should automatically resize the image or drawing to the size of the tile. It will repaint the whole map when the tile size is changed, so this could take a few seconds.
private void x32ToolStripMenuItem_Click(object sender, EventArgs e)
{
TileEditor.TileSize = new Size(32, 32);
}
private void x16ToolStripMenuItem_Click(object sender, EventArgs e)
{
TileEditor.TileSize = new Size(16, 16);
}
Undo and Redo actions can now be easily achieved by calling a few functions. Undos are done in groups of saved tiles, you can create groups and add tiles to them with their saved values and then add the group to the Undo stack. The TileEditor control has several functions for adding tiles to its own UndoGroup which can then be added to the stack instead of creating your own group.
//Apply and clear the undo group if any tiles were in it already
TileEditor.ApplyAndClearUndoGroup();
//Add the selected tiles to the group
TileEditor.AddSelectionToUndoGroup();
//Other functions to add tiles to the group
TileEditor.AddTilesToUndoGroup(new Rectangle(0, 0, 5, 5));
TileEditor.AddTileToUndoGroup(new UndoTile(5, 3, 0, 2));
//Apply the group
TileEditor.ApplyAndClearUndoGroup();
In the demo the group is cleared when the mouse down event is called for the tile editor control and is applied in the mouse up event. Tiles are then added to it in the MouseMove event.
To activate selection for the control do TileEditor.AllowSelect = true;. Remember to unselect all the tiles when setting it to false. TileEditor.UnselectAll();
You can use the selected flag passed in the PaintEventArgs for the paint tile event to draw a different image or an inverted image to show it is selected. You can retrieve the selected tiles by doing TileEditor.SelectedTiles which returns a list of TilePoints. To copy the selected tiles do TileEditor.CopySelectedTiles();. The following code pastes the tiles after adding the tiles that are to be overwritten to the UndoStack.
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
//Apply and clear the undo group
TileEditor.ApplyAndClearUndoGroup();
//Add the pasting area to the undo group and apply it
TileEditor.AddTilesToUndoGroup(TileEditor.PastingSelectionArea);
TileEditor.ApplyAndClearUndoGroup();
//Paste tiles
TileEditor.PasteSelectedTiles();
}
| You must Sign In to use this message board. | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||