这本身有一个游戏开发项目,但它实际上是关于编码和将数据映射到其他数据片段。这就是为什么我决定在这里发布它。
我用于外部库存项目数据存储的格式:
[ID:IT_FO_TROUT]
[Name:Trout]
[Description:A raw trout.]
[Value:10]
[3DModel:null]
[InventoryIcon:trout]
[Tag:Consumable]
[Tag:Food]
[Tag:Stackable]
[OnConsume:RestoreHealth(15)]
[OnConsume:RestoreFatigue(15)]
问题集中在最后 2 个OnConsume属性上。基本上,这两个属性意味着当物品被消耗时,消费者的健康会增加 15 点,他的疲劳也会增加。这在后台调用了 2 种不同的方法:
void RestoreHealth(Character Subject, int Amount);
void RestoreFatigue(Character Subject, int Amount);
您将如何将这些方法映射到它们的文件内字符串对应项?这是我想到的:
每次消费一个项目时,都会将一个字符串列表(事件)传递给一个项目事件管理器。管理器解析每个字符串并调用适当的方法。非常容易设置,并且由于这不是经常发生的操作,因此对性能的影响可能不会很大(字符串的大小也会很小(最多 10-15 个字符),并且在 O(n) 时间内解析)。
每个库存项目(类)在初始化时解析字符串事件一次且仅一次。每个字符串事件都通过字典。就性能而言,这是我能想到的最有效的方法,但它使做其他事情变得极其困难:字典中的所有值都必须是同一类型的委托。这意味着我无法保留
a) 恢复健康(int)
b) SummonMonster(位置,计数)
在同一个字典中,并且必须为每种可调用方法设置一个新的数据结构。这是一项巨大的工作量。
想到了一些改进这两种方法的方法:
我可以在Item 事件管理器中使用某种临时缓存,这样一个项目的OnConsume事件就不会被解析两次?不过,我可能会遇到与我在 2) 中遇到的问题相同的问题,因为缓存必须是
map<InventoryItem,List<delegate>>
..NET 库中的哈希表数据结构允许任何类型的对象在任何给定时间成为键和/或值(与字典不同)。我可以使用它并将字符串 A 映射到委托 X,同时也将字符串 B 映射到 同一结构中的 Y 委托。为什么我不应该这样做?你能预见这种方法会带来什么麻烦吗?
我也在思考反思的方式,但我并不完全有经验。而且我很确定每次解析字符串都会更快。
编辑
我的最终解决方案,考虑到 Alexey Raga 的回答。为每种事件使用接口。
public interface IConsumeEvent
{
void ApplyConsumeEffects(BaseCharacter Consumer);
}
示例实施者(特定事件):
public class RestoreHealthEvent : IConsumeEvent
{
private int Amount = Amount;
public RestoreHealthEvent(int Amount)
{
this.Amount = Amount;
}
public void ApplyConsumeEffects(BaseCharacter Consumer)
{
Consumer.Stats.AlterStat(CharacterStats.CharStat.Health, Amount);
}
}
在解析器内部(我们关心事件特殊性的唯一地方 - 因为我们正在解析数据文件本身):
RestoreHealthEvent ResHealthEv = new RestoreHealthEvent (Value);
NewItem.ConsumeEvents.Add (ResHealthEv );
当角色消耗物品时:
foreach (IConsumeEvent ConsumeEvent in Item.ConsumeEvents)
{
//We're inside a parent method that's inside a parent BaseCharacter class; we're consuming an item right now.
ConsumeEvent.ApplyConsumeEffects(this);
}