对数据结构的建议:“船体”内的盒子

时间:2015-07-06 19:54:12

标签: c# xml wpf data-structures 2d-games

我正在制作(2D)宇宙飞船游戏,而我无法找到一种节省太空船数据的有效方法。

我有一个“船体”(边界),所有的系统/房间都在这里。房间是连续的,有些系统也是如此。我想有效地保存船体和房间数据,以便于操纵它们(在房间之间增加/减去空间,延伸和/或损坏船体等),并轻松地将它们保存在(最好)人类可读的格式中。 / p>

到目前为止我看到的是两个选项:

  • 在二维数组对象中保存所有“按像素”,这些对象包含房间这部分的“像素”(繁琐而且很容易导致错误,但最容易实现),或者
  • 通过类似树的数据结构进行保存,可以表示为XML(符合我的大多数要求,但我无法弄清楚如何很好地实现它 - “盒子模型”方法不会让我太过深入非长方形的房间。

如果它有任何区别,我正在使用(将使用)C#和Blend / WPF。如果有一个组件可以神奇地允许操纵孩子并将其序列化,那么我认为这也是可以接受的。

这是我在这个网站上的第一个问题,所以如果我做错了,请提及。谢谢你的时间。 :)

1 个答案:

答案 0 :(得分:1)

考虑到你可能有许多事情会使房间系统变得更加复杂:

  • 您的房间/系统可能具有属性,房间名称,房间类型,添加属性时的子类型,例如ComputerRoom可能具有NumberOfCPUCores作为属性,而这不适用于普通房间。 %伤害,伤害等等。
  • 重叠规则可能更复杂,例如您可能会在以后添加可能重叠或跨越多个房间的内容。

可以使用位图样式存储模型来表示简单的大小/形状和位置,但是如果没有伴随数据,它将不容易实现更复杂的结构。

我会考虑使用Data Contract serialization,这可以使用各种方法来存储和发送数据,包括但不限于以XML格式存储,二进制(更高效,但不是人类可读),通过网络发送使用WCF等。它允许扩展到几乎无限复杂的模型。

以下简单模型和XML序列化的示例。 (Everthing在这里是矩形的。)

船体,房间等的定义:

[DataContract]
class Hull
{
    public int Width { get; set; }
    public int Height { get; set; }

    [DataMember]
    public List<Component> Components { get; set; } 

    //read only properties will be ignored
    public int SurfaceArea { get { return Width*Height; }}

    //some properties can be excluded from serialization:
    [IgnoreDataMember]
    public int NotStoredInXml { get; set; }

    public Hull()
    {
        this.Components = new List<Component>();
    }

}

[DataContract]
[KnownType(typeof(Room))]
[KnownType(typeof(ComputerRoom))]
[KnownType(typeof(System))]
abstract class Component
{
    [DataMember]
    int Width { get; set; }
    [DataMember]
    int Height { get; set; }
    [DataMember]
    int X { get; set; }
    [DataMember]
    int Y { get; set; }
}

[DataContract] class Room : Component { }
[DataContract] class System : Component { }
[DataContract] class ComputerRoom : Room
{
    [DataMember]
    public int NumberOfCPUCores { get; set; }
}

保存和加载数据:

var hull = new Hull();
hull.Components.Add(new ComputerRoom { NumberOfCPUCores = 3 });
hull.Components.Add(new System());
hull.Components.Add(new Room());

var serializer = new DataContractSerializer(typeof (Hull));
using (var stream = File.Open("test.xml", FileMode.Create))
{
    serializer.WriteObject(stream, hull);
}

Hull newHull;
using (var stream = File.OpenRead("test.xml"))
{
    newHull = serializer.ReadObject(stream) as Hull;
}

Console.WriteLine(newHull.Components.Count); //3

生成的XML:

<Hull xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication22" 
      xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Components>
    <Component i:type="ComputerRoom">
        <Height>0</Height>
        <Width>0</Width>
        <X>0</X>
        <Y>0</Y>
        <NumberOfCPUCores>3</NumberOfCPUCores>
    </Component>
    <Component i:type="System">
        <Height>0</Height>
        <Width>0</Width>
        <X>0</X>
        <Y>0</Y>
    </Component>
    <Component i:type="Room">
        <Height>0</Height>
        <Width>0</Width>
        <X>0</X>
        <Y>0</Y>
        </Component>
    </Components>
</Hull>

<强>更新

如果要支持任意形状,可以查看WPF中的Path语法 和Geometry Class