瓦片编辑器控件
用于以瓦片形式编辑地图或小图片的控件。
引言
TileEditor
控件编辑瓦片的网格。 它可用于快速创建基于瓦片的游戏的快速编辑器。 它支持具有多个图层的 2D 网格,并且可以使用 GDI 相对较快地进行绘制。
当前版本支持编辑小型和中型地图,瓦片的多重选择,瓦片的复制和粘贴以及多个撤消和重做操作。
背景
我经常需要一个瓦片编辑控件,以便我可以快速制作编辑器来编辑基于瓦片的游戏的地图。 当时周围没有,所以我决定创建自己的。 该控件是一个快速绘制瓦片编辑器,让您可以快速轻松地创建多种编辑器。
历史
- 2.0 (08 年 5 月 27 日)
- 添加了瓦片选择功能。
- 添加了瓦片的复制和粘贴功能。
- 添加了撤消和重做操作。
使用控件
绘制地图
TileEditor
控件可以像任何其他控件一样使用。 地图和瓦片大小是简单的属性,您可以在设计时和运行时进行更改。 要在瓦片之间添加间距,您可以将 TileSpacing
属性设置为您想要的瓦片之间的像素数。 要绘制瓦片,有一个名为 PaintTile
的事件,该事件传递一个 TileEventArgs
实例,其中包含正在绘制的瓦片的位置和 PaintEventArgs
实例。 然后您可以绘制任何您喜欢的东西; 以下示例来自演示,如果选择了瓦片图像,则绘制反转的瓦片图像,如果未选择,则绘制正常的瓦片图像。
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);
}
}
编辑地图
要编辑地图,您需要添加 MouseDown
事件。 这将传递 MouseTileEventArgs
实例,其中包含单击的瓦片的位置。 您可以添加代码以任何方式更改瓦片; 在演示中,有两个选定的瓦片(一个用于鼠标左键单击,一个用于鼠标右键单击)。 如果按住 shift 键,它将编辑底层而不是顶层。 对于拖动时的连续编辑,您需要在 MouseMove
事件中执行相同的代码。 为了提高效率,您可以记录鼠标所在的最后一个瓦片,并且仅当最后一个瓦片与当前瓦片不同时才编辑瓦片。 示例如下
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;
}
获取不同的缩放级别
只需更改瓦片大小即可轻松完成缩放级别。 在 PaintTile
事件中绘制时,它应该自动将图像或绘图调整为瓦片的大小。 更改瓦片大小时,它将重新绘制整个地图,因此这可能需要几秒钟。
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);
}
撤销和重做
现在可以通过调用几个函数轻松实现撤消和重做操作。 撤消是以保存的瓦片组完成的,您可以创建组并将瓦片及其保存的值添加到其中,然后将该组添加到撤消堆栈。 TileEditor 控件有几个函数用于将瓦片添加到其自己的 UndoGroup,然后可以将其添加到堆栈中,而不是创建自己的组。
//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();
在演示中,当为瓦片编辑器控件调用鼠标按下事件时,该组将被清除,并在鼠标抬起事件中应用。 然后将瓦片添加到 MouseMove 事件中。
选择、复制和粘贴
要激活控件的选择,请执行 TileEditor.AllowSelect = true;
。 请记住在将其设置为 false 时取消选择所有瓦片。 TileEditor.UnselectAll();
您可以使用在 PaintEventArgs 中传递的 selected 标志来进行 paint tile 事件,以绘制不同的图像或反转的图像来显示它已被选中。 您可以通过执行 TileEditor.SelectedTiles
来检索选定的瓦片,该方法返回 TilePoints 的列表。 要复制选定的瓦片,请执行 TileEditor.CopySelectedTiles();
。 以下代码在将要覆盖的瓦片添加到 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();
}
已知bug
- 大型地图。 目前,存储了整个地图的图像,以便控件可以实现快速绘制,因此如果图像太大,您可能会收到“内存不足”错误。