对数据结构的建议:在“外壳”内的盒子

本文关键字:外壳 盒子 数据结构 | 更新日期: 2023-09-27 18:01:20

我正在制作一款(2D)宇宙飞船游戏,但我还不知道如何有效地保存宇宙飞船数据。

我有一个"船体"(边界),所有的系统/房间都在其中。房间是连续的,有些系统也是。我想有效地保存船体和房间数据,以便易于操作(添加/减去房间之间的空间,扩展和/或损坏船体等),并轻松地将它们保存在(最好)人类可读的格式。

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

  • 将所有内容"按像素"保存在2D对象数组中,其中包含房间的"像素"部分(虽然最容易实现,但繁琐且容易导致错误),或者
  • 通过树状数据结构保存,可表示为XML(符合我的大多数要求,但我不知道如何很好地实现它-"盒子模型"方法不会让我进入非矩形的房间太远)。

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

这是我在这个网站上的第一个问题,所以如果我做错了什么,请告诉我。谢谢你的宝贵时间。:)

对数据结构的建议:在“外壳”内的盒子

考虑到你可能有一些东西会使房间系统更复杂:

  • 您的房间/系统可能有属性,房间名称,房间类型,添加属性时的子类型,例如,电脑室可能有NumberOfCPUCores作为属性,而这不适用于普通房间。%损坏,损坏位置等。
  • 重叠规则可能更复杂,例如,您可能稍后添加一些可以重叠或跨越多个房间的东西。

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

我会考虑使用数据契约序列化,这使得存储和发送数据的方法范围很广,包括但不限于存储为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语法和几何类