39传奇素材网 发表于 2025-7-10 17:49:33

传奇游戏中,如何实现装备系统与角色系统的解耦

在传奇游戏中,装备系统与角色系统的解耦是模块化设计的关键。以下是实现两者解耦的核心方法和技术方案:
1. 基于接口而非实现的依赖
让装备系统和角色系统通过抽象接口交互,而非直接依赖具体实现。
定义属性接口
lua
-- attribute_interface.lua
local AttributeInterface = {}

-- 获取基础属性
function AttributeInterface:get_base(attr_name)
    return 0 -- 默认实现,由具体模块重写
end

-- 修改属性
function AttributeInterface:modify(attr_name, value)
    -- 空实现,由具体模块实现
end

return AttributeInterface




装备系统通过接口修改属性
lua
-- equipment.lua
local AttributeInterface = require("attribute_interface")

local Equipment = {}
local equipped_items = {}

function Equipment:equip(character, item_id)
    -- 装备逻辑...
    local attrs = self:calculate_bonus(item_id)

    -- 通过接口修改属性,不直接依赖角色系统
    for attr, value in pairs(attrs) do
      character:modify(attr, value)
    end
end
2. 事件驱动的解耦
通过发布 - 订阅模式处理装备变更的副作用,避免直接调用。
事件管理器
lua
-- event_manager.lua
local EventManager = {}
local listeners = {}

function EventManager:on(event_name, callback)
    listeners = listeners or {}
    table.insert(listeners, callback)
end

function EventManager:emit(event_name, ...)
    local callbacks = listeners
    if callbacks then
      for _, callback in ipairs(callbacks) do
            callback(...)
      end
    end
end

return EventManager
装备变更触发事件
lua
-- equipment.lua
function Equipment:equip(item_id)
    -- 装备逻辑...
    EventManager:emit("equipment_changed", self.owner_id, item_id, "equip")
end

function Equipment:unequip(item_id)
    -- 卸下逻辑...
    EventManager:emit("equipment_changed", self.owner_id, item_id, "unequip")
end
角色系统监听事件
lua
-- character.lua
function Character:init()
    -- 监听装备变更事件
    EventManager:on("equipment_changed", function(owner_id, item_id, action)
      if owner_id == self.id then
            self:update_attributes() -- 重新计算属性
      end
    end)
end
3. 数据与表现分离
装备数据和角色属性数据独立存储,通过数据映射关联。
装备数据模型
lua
-- equipment_data.lua
local EquipmentData = {}

function EquipmentData:get_bonus(item_id)
    local config = require("item_config")
    return config.attributes or {}
end

function EquipmentData:get_set_effects(set_id, piece_count)
    -- 计算套装效果
end

return EquipmentData
角色属性数据
lua
-- character_attributes.lua
local CharacterAttributes = {}
local attrs = {}

function CharacterAttributes:init(character_id)
    attrs = {
      base = {},      -- 基础属性
      equipment = {}, -- 装备加成
      total = {}      -- 最终属性
    }
end

function CharacterAttributes:update_equipment_bonus(character_id, bonus)
    attrs.equipment = bonus
    self:recalculate(character_id)
end

function CharacterAttributes:recalculate(character_id)
    -- 重新计算最终属性
    local base = attrs.base
    local equip = attrs.equipment

    attrs.total = {}
    for attr, value in pairs(base) do
      attrs.total = value + (equip or 0)
    end
end

return CharacterAttributes
4. 中间层服务代理
引入中间层服务处理装备与角色的交互,避免直接依赖。
属性服务
lua
-- attribute_service.lua
local AttributeService = {}
local AttributeInterface = require("attribute_interface")
local CharacterAttributes = require("character_attributes")

function AttributeService:register_character(character_id, interface)
    -- 注册角色属性接口实现
end

function AttributeService:apply_equipment_bonus(character_id, bonus)
    local character = self:get_character(character_id)
    if character then
      character:modify("equipment", bonus)
    end
end

return AttributeService
装备系统通过服务修改属性
lua
-- equipment.lua
function Equipment:equip(item_id)
    -- 计算属性加成
    local bonus = self:calculate_bonus(item_id)

    -- 通过服务应用加成,不直接接触角色系统
    AttributeService:apply_equipment_bonus(self.owner_id, bonus)
end
5. 组合而非继承
角色系统不继承装备系统,而是组合装备管理器。
角色系统组合装备管理器
lua
-- character.lua
local Character = {}

function Character:create(id)
    local instance = {
      id = id,
      equipment = require("equipment_manager"):new(id), -- 组合装备管理器
      attributes = require("character_attributes"):new(id)
    }

    -- 设置装备变更回调
    instance.equipment:on_change(function(bonus)
      instance.attributes:update_equipment_bonus(bonus)
    end)

    return instance
end

return Character
6. 配置驱动的属性映射
通过配置文件定义装备属性到角色属性的映射关系,避免硬编码。
属性映射配置
lua
-- attribute_mapping.lua
return {
    -- 装备属性 -> 角色属性映射
    ["weapon_attack"] = "attack",
    ["armor_defense"] = "defense",
    ["ring_health"] = "max_health",
    -- 复杂映射示例
    ["set_bonus_1"] = function(character, value)
      character:add_buff("attack_speed", value * 0.01)
    end
}
装备系统使用映射
lua
-- equipment.lua
local mapping = require("attribute_mapping")

function Equipment:calculate_character_bonus()
    local result = {}
    for equip_attr, value in pairs(self.equipped_items) do
      local char_attr = mapping
      if char_attr then
            if type(char_attr) == "function" then
                char_attr(self.owner, value) -- 执行自定义映射函数
            else
                result = (result or 0) + value
            end
      end
    end
    return result
end
7. 单元测试验证解耦
编写单元测试确保装备系统和角色系统可以独立修改和测试。
装备系统测试
lua
-- test_equipment.lua
local Equipment = require("equipment")
local MockAttributeInterface = {}

function MockAttributeInterface:modify(attr, value)
    -- 记录属性修改,用于断言
    self.modified = self.modified or {}
    self.modified = (self.modified or 0) + value
end

-- 测试装备添加属性
local mock = MockAttributeInterface
local equipment = Equipment:new(mock)
equipment:equip("sword")

assert(mock.modified.attack == 100, "攻击属性未正确添加")
解耦的优势
独立开发:装备系统和角色系统可由不同团队并行开发。
独立测试:可单独测试装备属性计算逻辑。
灵活扩展:新增装备类型或角色职业无需修改对方代码。
降低风险:修改装备系统不会意外影响角色系统。
总结
通过接口抽象、事件驱动、数据分离、服务代理和配置映射,可以实现装备系统与角色系统的彻底解耦。这种设计使系统更具弹性,能更好地应对游戏需求的变化,同时保持代码的可维护性和可测试性。

页: [1]
查看完整版本: 传奇游戏中,如何实现装备系统与角色系统的解耦