Files
2026-03-05 11:39:06 +08:00

116 lines
4.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Fantasy.Entitas;
#pragma warning disable CS8603 // Possible null reference return.
namespace Fantasy;
public static class ItemFactory
{
/// <summary>
/// 创建一个物品
/// </summary>
/// <param name="scene"></param>
/// <param name="configId"></param>
/// <param name="count"></param>
/// <param name="isBind"></param>
/// <returns></returns>
public static Item Create(Scene scene, uint configId, int count, bool isBind)
{
var itemConfig = ItemConfigData.Instance.Get(configId);
if (itemConfig.Superposed)
{
if (itemConfig.SuperposedMax < count)
{
Log.Error($"物品{itemConfig.Name} 最大叠加数量为{itemConfig.SuperposedMax},不能超过{count}");
return null;
}
}
else
{
if (count > 1)
{
Log.Error($"物品{itemConfig.Name} 不支持叠加不能超过1个");
return null;
}
}
var item = Entity.Create<Item>(scene, true, true);
item.ConfigId = configId;
item.Count = count;
item.IsBind = isBind;
// 根据物品的类型单独的做一些处理
switch ((ItemType)itemConfig.Type)
{
case ItemType.Drug:
{
break;
}
case ItemType.Equip:
{
// 装备的要挂载装备组件。
item.AddComponent<EquipComponent>();
break;
}
case ItemType.Prop:
{
break;
}
case ItemType.Garbage:
{
break;
}
}
return item;
}
/// <summary>
/// 批量创建物品
/// </summary>
/// <param name="scene"></param>
/// <param name="itemCreateParamsList"></param>
/// <param name="items"></param>
public static void Create(Scene scene, List<ItemCreateParams> itemCreateParamsList, List<Item> items)
{
// 也可以用Foreach但是性能会差一点点。
// for和Foreach性能差距非常小尤其是在现在的CPU用但如果在高频繁使用的场景下for提升会明显一些。
// 不要纠结到底是用for还是Foreach因为两者性能差距非常小而且Foreach更简洁。
// 以下是一个简单性能对比(处理 1000 万元素的 List<int>
// for 循环 ~50 ms
// foreach 循环 ~70 ms
// for 循环快约 20-30%(因硬件和 .NET 版本而异)。
// 为什么 for 更快?
// 直接索引访问List<T> 底层是数组,索引访问是 O(1) 操作。
// 避免迭代器开销foreach 需要调用 MoveNext() 和 Current隐含版本检查防止遍历时集合被修改
// 什么时候用 foreach
// 代码简洁性优先不需要索引时foreach 更易读。
// 复杂集合类型:对于非 List<T> 的集合(如 IEnumerable<T> 或字典foreach 可能更高效,因为某些集合的索引访问是 O(n)(如 LinkedList<T>)。
// 优化建议
// 优先选择 for如果性能敏感且需要高频遍历大规模数据。
// 使用 foreach如果代码可读性更重要或遍历非数组结构的集合。
// 避免在 List<T> 中使用 foreach 的陷阱:
// 如果遍历过程中修改集合(如增删元素),会触发 InvalidOperationException。
// 对值类型集合(如 List<struct>foreach 可能涉及装箱(但 List<T> 的 Enumerator 是结构体,不会发生装箱)。
// 高级场景
// Span<T> 或数组:对于 Span<T> 或原生数组for 循环可以进一步优化为 SIMD 指令。
// for (var index = 0; index < itemCreateParamsList.Count; index++)
// {
// var itemCreateParams = itemCreateParamsList[index];
// var item = Create(scene, itemCreateParams.ConfigId, itemCreateParams.Count, itemCreateParams.IsBind);
// items.Add(item);
// }
foreach (var itemCreateParams in itemCreateParamsList)
{
var item = Create(scene, itemCreateParams.ConfigId, itemCreateParams.Count, itemCreateParams.IsBind);
items.Add(item);
}
}
}