游戏开发:基础模块之buff加成系统设计方案

  • 写一写游戏项目的基础模块的实现思路,之buff系统:

通常把加成BUFF根据生效场景区分为:战斗BUFF(fight buff)和非战斗BUFF(non fight buff);

加成信息可能来自于任意模块和系统中,具备分散的特点,设计上:

为每种buff定义来源类型(fromType);

在统一BUFF模块中,为每种buff定义管理逻辑代理器(proxy);

实现代理器管理模块(manager),封装对外查询更新API;

外部加成代理器(proxy)

代理逻辑具有通用性,抽象出通用基类公共继承(Base);

每个代理器关联外部指定模块,外部模块需要提供查询和更新BUFF接口;

认为buff数据计算获取是高消耗的,代理器维护计算结果缓存,优化性能消耗;外部模块加成信息变更时通过事件触发缓存的刷新和重建;

local Base = {
    getId = function(self)
        return nil
    end,
    getName = function(self)
        return nil
    end,
    getInlineModule = function(self)
        return nil
    end,
    getFightCache = function(self)
        return nil
    end,
    setFightCache = function(self, cache)
        return nil
    end,
  	-- 非战斗BUFF维护同理
}

-- 从外部关联模块获取加成信息
function Base:getRawFightBuffInfo()
    return require(self.getInlineModule()).getFightBuffInfo()
end

-- 格式化加成信息为buff模块内部通用格式
function Base:packFightBuff(buffInfo)
    return buffInfo -- format buff info
end

function Base:getFightBuff()
    local info = self:getFightCache()
    if not info then
        info = self:getRawFightBuffInfo() or {}
        self:setFightCache(info)
    end
    return self:packFightBuff(info)
end

-- 刷新加成缓存,当外部模块加成发生变化时触发
function Base:refrush(rebuild)
    self:setFightCache(nil)
    if rebuild then
        self:getFightBuff()
    end
end

-- 通知代理管理模块关注的事件
function Base:getCBFunction()
    return {}
end

return Base

代理器管理模块(manager)

管理为外部模块代理加成逻辑的代理器对象,并提供外部接口、转发事件;

local Const = {
    FROM_TYPE_HERO_HANDBOOK = 1,
    FROM_TYPE_HERO_SKIN = 2,
}

Const.type2path = {
    [Const.FROM_TYPE_HERO_HANDBOOK] = "hero_handbook",
    [Const.FROM_TYPE_HERO_SKIN] = "hero_skin",
}

local fromType2Object = {}

-- 创建代理器对象
local function newObject(fromType)
    local path = string.format("%s.%s", "module.buff.template", Const.type2path[fromType])
    local module = require(path)
    local object = setmetatable({}, {__index = module})
    fromType2Object[fromType] = object
    return object
end

local function getObject(fromType)
    local object = fromType2Object[fromType]
    if not object then
        object = newObject(fromType)
    end
    return object
end

-- 统计给定的fromType的加成信息
local function getFightBuffList(fromTypeList)
    local buffList = {}
    for _, fromType in ipairs(fromTypeList) do
        local object = getObject(fromType)
        table.extend(buffList, object:getFightBuff())
    end
    return buffList
end

-- INTERFACE
-- 定义出外部需要使用的查询接口,内部转换成对fromType的查询
function Manager.getHeroFightBuff()
    local fromTypes = {Const.FROM_TYPE_HERO_HANDBOOK, Const.FROM_TYPE_HERO_SKIN}
    return getFightBuffList(fromTypes)
end

-- 转发外部模块的触发事件
function Manager.trigEvent(ev, ...)
    local objects = Manager.getHookObjects(ev)
    for _, object in ipairs(objects) do
        object:refrush()
    end
end

return Manager
posted @ 2025-05-22 23:49  linxx-  阅读(64)  评论(0)    收藏  举报