游戏开发:基础模块之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
本文来自博客园,作者:linxx-,转载请注明原文链接:https://www.cnblogs.com/linxx-/p/18892217
浙公网安备 33010602011771号