读取XML(Map / TileSet数据)并将其绘制到面板 - C#

时间:2014-05-15 13:02:02

标签: c# xml tiles

我试图在C#中制作一个简单的基于磁贴的游戏引擎,只是为了好玩。

当我只是加载图像并将其全部绘制在2 for for循环中的面板上时,它可以正常工作。现在我决定制作一个Map类来处理XML地图,但它没有像我预期的那样工作。

我认为,问题出在XML阅读器部分,但我不知道那是什么。

正如您在下图所示,默认" noimage"正在面板上显示。但是,它需要使用xml文件中的信息显示地图。 (加载图像,将其切割成瓷砖,然后将其绘制到for循环内的面板上。)

Form1中的主要代码:

Map testmap = new Map("test.xml");

for (int y = 0; y < testmap.Height; y += 1)
{
    for (int x = 0; x < testmap.Width; x += 1)
    {
        int t = int.Parse(testmap.Data[y].Substring(x, 1));
        e.Graphics.DrawImage(testmap.TileSet, new Rectangle(x*32, y*32, 32, 32), testmap.Tiles[t], GraphicsUnit.Pixel); 
    }
}

Map.cs:

class Map
{
    public string File = "";
    public int Width = 0;
    public int Height = 0;

    public List<string> Data = new List<string>();

    public Image TileSet = Image.FromFile("data/tiles/default.png");
    public List<Rectangle> Tiles = new List<Rectangle>();

    public Map(string fname)
    {
        File = fname;
        XmlTextReader xml = new XmlTextReader("data/maps/" + File);
        while (xml.Read())
        {
            if (xml.Name == "tileset")
            {
                XmlTextReader xml2 = new XmlTextReader("data/tiles/" + xml.Value);
                while (xml2.Read())
                {
                    if (xml2.Name == "image")
                    {
                        TileSet = Image.FromFile("data/tiles/" + xml2.Value);
                    }
                    else if (xml2.Name == "tile")
                    {
                        xml2.MoveToAttribute("x");
                        int x = int.Parse(xml2.Value);
                        xml2.MoveToAttribute("y");
                        int y = int.Parse(xml2.Value);

                        Tiles.Add(new Rectangle(x, y, 32, 32));
                    }
                }
            }
            else if (xml.Name == "w")
            {
                Width = int.Parse(xml.Value);
            }
            else if (xml.Name == "h")
            {
                Height = int.Parse(xml.Value);
            }
            else if (xml.Name == "row")
            {
                Data.Add(xml.Value);
            }
        }
    }
}

数据/地图/ map.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Test Map -->
<tileset>grass.xml</tileset>
<w>16</w>
<h>16</h>
<map>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
</map>

数据/瓦/ grass.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Grass TileSet -->
<image>grass.png</image>
<tileset>
    <tile x="16" y="48"></tile>
    <tile x="0" y="0"></tile>
</tileset>

The problem

1 个答案:

答案 0 :(得分:2)

Iv基本上改变了整个系统。 iv设法将地图绘制成窗体。

以下是Map类的外观:

[XmlTypeAttribute(AnonymousType = true)]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Map
{
    private string[] tilesetField;
    private byte widthField;
    private byte heightField;
    private string[] dataField;

    [XmlArrayItemAttribute("tile", IsNullable = false)]
    public string[] tileset
    {
        get
        {
            return tilesetField;
        }
        set
        {
            tilesetField = value;
        }
    }

    public byte width
    {
        get
        {
            return widthField;
        }
        set
        {
            widthField = value;
        }
    }

    public byte height
    {
        get
        {
            return heightField;
        }
        set
        {
            heightField = value;
        }
    }

    [XmlArrayItemAttribute("row", IsNullable = false)]
    public string[] data
    {
        get
        {
            return dataField;
        }
        set
        {
            dataField = value;
        }
    }
}

这就是你的XML看起来的样子:

<?xml version="1.0" encoding="UTF-8"?>
<Map>
  <tileset>
    <tile>grass.png</tile>
    <tile>grass1.png</tile>
  </tileset>
  <width>16</width>
  <height>16</height>
  <data>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
    <row>0001000000001000</row>
    <row>0000000110000000</row>
    <row>0000000000000000</row>
  </data>
</Map>

现在您可以像这样简单地绘制地图:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    XmlSerializer ser = new XmlSerializer(typeof(Map));
    Map testmap;
    using (XmlReader reader = XmlReader.Create("test.xml"))
    {
        testmap = (Map)ser.Deserialize(reader);
    }

    for (int y = 0; y < testmap.height; y += 1)
    {
        for (int x = 0; x < testmap.width; x += 1)
        {
            int t = int.Parse(testmap.data[y].Substring(x, 1));
            e.Graphics.DrawImage(Image.FromFile(testmap.tileset[t]), new Rectangle(x * 32, y * 32, 32, 32));
        }
    }
}

基本上,XML可以准确地解释它是如何工作的 首先,就像你的第一个设计一样,地图有宽度和高度。地图还有图块,这些图块列在图块集中。它们所在的顺序是瓷砖的索引。 然后,地图的数据是图块索引的行和列。