我有一款游戏已经开发了一段时间了。核心是 C++,但我使用 Python 来编写脚本和攻击/状态效果/项目等。
我已经把自己编码到了一个角落,我必须使用 eval 来获得我想要的行为。它是这样产生的:
我有一个 xml 文档,用于规范攻击,如下所示:
<Attack name="Megiddo Flare" mp="144" accuracy="1.5" targetting="EnemyParty">
<Flags>
<IgnoreElements/>
<Unreflectable/>
<ConstantDamage/>
<LockedTargetting/>
</Flags>
<Components>
<ElementalWeightComponent>
<Element name="Fire" weight="0.5"/>
</ElementalWeightComponent>
<ConstantDamageCalculatorComponent damage="9995" index="DamageCalculatorComponent"/>
</Components>
</Attack>
我用 python 解析这个文件,并构建我的攻击。每个攻击由任意数量的组件组成,以实现不同的行为。在这个攻击的例子中,我实现了 DamageCalculatorComponent,告诉 python 使用 ConstantDamage 变体。我在脚本文件中实现了所有这些组件。这对于我经常使用的组件类型来说非常好。在某些攻击中,该攻击将是使用该特定组件变体的唯一攻击。我希望能够在 xml 文件中指定 Component 类,而不是将组件添加到我的脚本文件中。
例如,如果我要实现《最终幻想》中的经典白风攻击(根据攻击者的生命值恢复团队生命值)
<Attack name="White Wind" mp="41" targetting="AnyParty">
<Flags>
<LockedTargetting/>
</Flags>
<Components>
<CustomComponent index="DamageCalculatorComponent">
<![CDATA[
class WhiteWindDamageComponent(DamageCalculatorComponent):
def __init__(self, Owner):
DamageCalculatorComponent.__init__(self, Owner)
def CalculateDamage(self, Action, Mechanics):
Dmg = 0
character = Action.GetUsers().GetFirst()
SM = character.GetComponent("StatManagerComponent")
if (SM != None):
Dmg = -SM.GetCurrentHP()
return Dmg
return WhiteWindDamageComponent(Owner)
]]>
</CustomComponent>
</Components>
</Attack>
我想知道是否有更好的方法来做到这一点?我能看到的唯一其他方法是将每个可能的组件变体定义放入我的 python 文件中,并展开我的组件创建者以检查其他变体。对于一次性使用的组件来说似乎有点浪费。是否有更好/更安全的替代方案来动态生成类型,或者可能是我没有看到的另一种解决方案?
提前致谢
最佳答案
内联 Python 很糟糕,因为
Python 源代码编辑器无法理解您的源代码文件,您将错过语法突出显示
所有其他工具,例如 pylint,可用于检查和验证源代码也将失败
替代方案
在元素<CustomComponent index="DamageCalculatorComponent">
...添加参数script
:
<CustomComponent index="DamageCalculatorComponent" script="damager.py">
然后添加文件damager.py
文件系统中的某处。
按照此处所述加载它:What is an alternative to execfile in Python 3?
在您的主游戏引擎代码中,从加载的系统模块中构造类,例如:
damager_class = sys.modules["mymodulename"].my_factory_function()
所有 Python 模块必须共享某种约定的类名/入口点函数。
如果你想拥有真正的可插拔架构,请使用 Python Eggs 和 setup.py
入口点
示例
关于python - 如何在 python 中避免使用 eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10357119/