2012-04-27 45 views
1

我有一段遊戲,我一直在努力。核心是C++,但我使用Python進行腳本編寫和攻擊/狀態效果/項目等。如何在python中使用eval

我已經把自己編碼到一個角落,我不得不使用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> 

。每個攻擊由任意數量的組件組成,以實現不同的行爲。在這個攻擊的例子中,我實現了一個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> 

我想知道是否有可能是一個更好的方式(通過HP的攻擊量恢復團隊HP)去做這個?我能看到的唯一方法是將每個可能的組件變體定義放入我的python文件中,並展開我的組件創建器以檢查其他變體。對於一次性使用組件來說似乎有點浪費。是否有更好/更安全的替代方案來動態生成類型,或者我沒有看到另一種解決方案?

在此先感謝

+2

我認爲在單獨的python模塊中使用組件定義似乎是一個更好的主意,而不是必須使用eval。如果你將不得不提供Python代碼,爲什麼不在Python模塊中? – MAK 2012-04-27 20:09:21

+0

我不知道是否有更好的解決方案不會做xml,但有一個metaclass的python類,增加了與xsd會做的相似的限制... – 2012-04-27 20:11:01

+1

Seconding MAK和Doug T.除非有其他信息, XML的這個 - 不要。 – senderle 2012-04-27 20:14:21

回答

2

內嵌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雞蛋和setup.py切入點

+0

和遊戲祝你好運,看起來很有前途:) – 2012-04-27 22:33:20