65.9K
CodeProject 正在变化。 阅读更多。
Home

瓦片编辑器控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (19投票s)

2008年5月13日

CPOL

3分钟阅读

viewsIcon

81550

downloadIcon

3422

用于以瓦片形式编辑地图或小图片的控件。

screen1.png

引言

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;
}

获取不同的缩放级别

screen2.png

只需更改瓦片大小即可轻松完成缩放级别。 在 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

  • 大型地图。 目前,存储了整个地图的图像,以便控件可以实现快速绘制,因此如果图像太大,您可能会收到“内存不足”错误。
© . All rights reserved.