GDScript字典与多物品处理:Roguelike类游戏物品加成系统实现咨询
Roguelike类游戏(如《Doomsday Hunters》)物品加成系统实现
1. 物品数据存储优化
不用给每个物品冗余定义所有属性,完全可以用**键值对(字典)**只存储物品的有效属性。比如一个仅提升攻击力的物品,只需存{"attack": 5, "desc": "提升5点攻击力"},无关属性直接忽略,数据库和内存里都这么存,既省空间又逻辑清晰。
2. 高效属性计算方案
不需要每次使用属性时遍历背包检查,核心思路是维护实时更新的属性缓存:
- 玩家获得/移除物品时,直接将物品的属性值同步到缓存(加/减操作)
- 读取属性时直接取缓存值,无需遍历物品列表
- 对于“攻击触发灼烧”这类非数值的复杂效果,单独维护一个被动效果列表,战斗时只遍历这个列表触发逻辑,而非所有物品
伪代码示例:
// 玩家类简化示例 public class Player { private Dictionary<string, int> _baseAttrs = new() { {"Attack", 10}, {"Defense", 5} }; private Dictionary<string, int> _bonusAttrs = new(); private List<IPassiveEffect> _passives = new(); public void AddItem(Item item) { // 同步数值属性到缓存 foreach (var (attr, val) in item.Attributes) { if (_bonusAttrs.ContainsKey(attr)) _bonusAttrs[attr] += val; else _bonusAttrs[attr] = val; } // 添加被动效果 if (item.Passive != null) _passives.Add(item.Passive); } public int GetTotalAttr(string attr) { _baseAttrs.TryGetValue(attr, out int baseVal); _bonusAttrs.TryGetValue(attr, out int bonusVal); return baseVal + bonusVal; } }
《Super Auto Pets》类队友装备系统实现
这类游戏的核心是每个队友单位独立维护自身的装备状态与属性缓存,逻辑和玩家系统类似,但多了单位维度的区分:
1. 单位与装备的绑定
每个队友(宠物)拥有自己的装备槽、属性缓存和被动效果列表,物品只能绑定到指定单位的槽位中,不会影响其他单位。
2. 装备/卸下的核心逻辑
- 装备物品时,将物品属性累加至该单位的属性缓存,被动效果加入其效果列表
- 卸下物品时反向操作:扣除对应属性值,移除被动效果
- 战斗结算时,针对每个单位的缓存属性和效果列表计算战斗表现
伪代码示例:
// 宠物类简化示例 public class Pet { public string Name { get; } private Dictionary<string, int> _baseAttrs; private Dictionary<string, int> _bonusAttrs = new(); private List<IPetPassive> _passives = new(); private Item[] _itemSlots; // 固定数量的装备槽 public Pet(string name, Dictionary<string, int> baseAttrs, int slotCount) { Name = name; _baseAttrs = baseAttrs; _itemSlots = new Item[slotCount]; } public void EquipItem(Item item, int slotIndex) { // 先处理槽位原有物品 if (_itemSlots[slotIndex] != null) { var oldItem = _itemSlots[slotIndex]; // 扣除旧物品属性 foreach (var (attr, val) in oldItem.Attributes) { _bonusAttrs[attr] -= val; if (_bonusAttrs[attr] <= 0) _bonusAttrs.Remove(attr); } // 移除旧物品被动 if (oldItem.PetPassive != null) _passives.Remove(oldItem.PetPassive); } // 装备新物品 _itemSlots[slotIndex] = item; foreach (var (attr, val) in item.Attributes) { if (_bonusAttrs.ContainsKey(attr)) _bonusAttrs[attr] += val; else _bonusAttrs[attr] = val; } if (item.PetPassive != null) _passives.Add(item.PetPassive); } }
内容的提问来源于stack exchange,提问作者Marcelo João
相关产品推荐
相关产品推荐

