处理多个回调执行顺序的模式。

我正在使用Lua脚本作为游戏逻辑和插件开发的前端,用C#(Unity)开发角色扮演游戏。我有一个设计问题一直在思考,但似乎找不到答案。我正在实现Effect类,它提供了一个常见的接口来定义和处理影响角色或生物的效果,无论是由法术、附魔物品还是状态(瘫痪、害怕等)引起的。目标是尽可能灵活,并将效果代码与实际的角色组件/类解耦。

我希望效果能够访问回调,以便它可以改变发生在实体身上的事件。例如,如果角色的生命值发生了变化,活动的效果可以触发并在应用变化之前进行改变。以下是两个Lua示例,API应该很容易理解:

减半生命值损失的戒指效果:

onHealthAdjustment = function(entity, val)
    if val < 0 then val = math.floor(val / 2); end
    return val;
end

魔法护盾法术:

onHealthAdjustment = function(entity, val)
    if val < 0 then
        championProperties = entity.championProperties;
        if championProperties then
            championProperties:adjustMana(val);
        end
        return 0;
    else
        return val;
    end
end

那么,如何处理回调的执行顺序?

假设角色失去10点生命值。如果先处理戒指效果,它会将生命值降低到5,然后法术会将生命损失降低到0,并消耗5点法力值。

如果先处理法术效果,它会将生命损失降低到0,消耗10点法力值,然后戒指回调得到0并且什么也不做。

我可以添加效果优先级变量,但总会有一些变量具有相同的值。以最后一个应用为先,或者仅以最后一个应用为先,会导致愚蠢的漏洞,例如选择和点击背包中的物品,以确保效果的处理顺序……我看不到一种方法可以并行而不是按顺序调用回调……

我可能没有看到修复当前模式的明显方法,或者我需要改变另一种设计模式。我已经阅读了有关策略和观察者模式的文献,但似乎找不到明确的答案。这些情况通常如何处理?

谢谢!

点赞
用户501459
用户501459

总会有一些具有相同值的东西

那又怎样呢?如果发生冲突,进行修复即可。应用效果的顺序不是任意的,它是你设计的一部分。

在你的代码中,你可能会有事件类型的事件处理程序列表,当事件发生时你需要遍历这个列表。只需确保该列表以正确的顺序(例如通过控制它们的注册顺序)进行即可。


附带说明:如果你不知道,这个:

 onHealthAdjustment = function(entity, val) end

可以写成这个样子:

 function onHealthAdjustment(entity, val) end
2015-07-16 14:55:56