保存相关常量的最佳实践是什么?

4
在我的游戏中,我有一个包含不同GameEntityType的枚举(大约有200个条目)。
当保存游戏时,只会将一个GameEntityType数组写入保存文件中。
为了重构游戏世界,并显示关于GameEntityTypes的各种信息, 我需要有更多额外细节(常量值)的列表。这意味着每个GameEntityType都有其他与之相关联的值。 这些值每帧非常频繁地被访问。 我的目标是以简单的方式从GameEntityTypeID(枚举)中获取所有额外信息。 例如,当我从savefile中读取0x1时,我可以通过像这样的数组轻松访问名称和所有隐含在数字/枚举中的其他信息:"Constants.TextureList[GameEntityType]" ,会返回字符串 "Stone_Texture.DDS"。
第一个enum entry的附加/关联信息示例:
类型: string,string,Flag-Enum:“Visual-Classification”,bool,bool 值: "StoneBlock","Stone_Texture.DDS",0x0102,false,true 对于每个附加信息类型,我创建了一个静态GameEntityTypeInfo类成员,如下所示: public static const string[] = {"StoneBlock", ... [more entrys]};
当然,这是一个可怕的解决方案,因为我不能随意添加GameEntityType而无需更新所有其他列表。 我还必须将逻辑单元分离为数据类型单元(这是一个问题!因为当我决定不再需要特定的EntityType时,我必须遍历超过6个列表!)
接下来,我尝试通过将这些数据集制作成结构体并将它们添加到静态数组中来解决此问题。 但在构造函数(即游戏启动时)创建具有附加信息的列表仍然不是最佳解决方案。
问题是:如何创建快速(名称/分类查找总计至少5000次每帧)和易于访问(最好使用索引器)这些常量值?
类似于以下查找将是最佳的“Constants.TextureList [GameEntityType]”。

什么是纹理列表?它与游戏实体类型有什么关系? - Joe
这是一个列表,我可以查找实体使用的纹理。 此外还会有一些其他列表:每个实体类型都有一个(或数组)列表,用于表示EntityType隐含的每个附加值。 - Riki
2个回答

2
通过子类化:
public abstract class Enumeration : IComparable
{
private readonly int _value;
private readonly string _displayName;

protected Enumeration()
{
}

protected Enumeration(int value, string displayName)
{
    _value = value;
    _displayName = displayName;
}

public int Value
{
    get { return _value; }
}

public string DisplayName
{
    get { return _displayName; }
}

public override string ToString()
{
    return DisplayName;
}

public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
{
    var type = typeof(T);
    var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

    foreach (var info in fields)
    {
        var instance = new T();
        var locatedValue = info.GetValue(instance) as T;

        if (locatedValue != null)
        {
            yield return locatedValue;
        }
    }
}

public override bool Equals(object obj)
{
    var otherValue = obj as Enumeration;

    if (otherValue == null)
    {
        return false;
    }

    var typeMatches = GetType().Equals(obj.GetType());
    var valueMatches = _value.Equals(otherValue.Value);

    return typeMatches && valueMatches;
}

public override int GetHashCode()
{
    return _value.GetHashCode();
}

public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
{
    var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
    return absoluteDifference;
}

public static T FromValue<T>(int value) where T : Enumeration, new()
{
    var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
    return matchingItem;
}

public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
{
    var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
    return matchingItem;
}

private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
{
    var matchingItem = GetAll<T>().FirstOrDefault(predicate);

    if (matchingItem == null)
    {
        var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
        throw new ApplicationException(message);
    }

    return matchingItem;
}

public int CompareTo(object other)
{
    return Value.CompareTo(((Enumeration)other).Value);
}
}

一篇文章在这里:http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx

谢谢,正是我想要的。 - Riki

0

不确定我是否完全理解你的意思,但听起来你需要的是一个 Dictionary<string, List<string>> 如果你想要快速查找。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接