数据结构建议:"hull" 中的框

Advice for data structure: boxes inside a "hull"

我正在制作一个 (2D) space飞船游戏,但我还没有找到一种有效的方法来保存 space飞船数据。

我有一个 "hull"(边界),所有 systems/rooms 都在其中。房间是连续的,一些系统也是如此。我想有效地保存船体和房间数据,以便于操作它们(adding/subtracting space 在房间之间,扩展 and/or 损坏船体等)并轻松地将它们保存在 (最好)human-readable格式。

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

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

这是我在这个网站上的第一个问题,如果我做错了什么请指出。谢谢你的时间。 :)

考虑到您可能有许多因素会使房间系统更加复杂:

  • 您的 rooms/systems 可能有属性、房间名称、房间类型、添加属性时的子类型,例如ComputerRoom 可能将 NumberOfCPUCores 作为 属性,而这不适用于普通房间。伤害百分比,伤害位置等
  • 重叠规则可能更复杂,例如您稍后可能会添加一些可以重叠或跨越多个房间的东西。

简单 size/shape 和位置可以使用位图样式存储模型来表示,但是如果没有附带数据,它不会轻易允许更复杂的结构。

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

下面是一个简单模型和 XML 序列化的示例。 (这里的一切都是矩形的)。

船体、房间等定义:

[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