我有一个游戏我已经做了一段时间了。核心是 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 文件中,并扩展我的组件创建者以检查其他变体。单次使用的组件似乎有点浪费。动态生成类型是否有更好/更安全的替代方案,或者我没有看到的另一种解决方案?
提前致谢