【问题标题】:Mixing class and instance variables together将类和实例变量混合在一起
【发布时间】:2015-02-13 17:02:05
【问题描述】:

我正在设计一个简单的角色扮演游戏(类似于《魔兽世界》、《英雄联盟》等),其中基本上有一个英雄或冠军与野生生物和其他英雄/冠军战斗。 然后,该英雄可以通过从战斗中获得经验值来升级,并且每个级别都会授予他一个技能点,这使他可以升级他的一项技能。 每个技能都有自己的目的并做自己的事情,技能的一个例子是:

class DamageAura(Skill):
    """
    This skill increases damage dealt by your hero,
    as well as deals damage back to the ones who attack your hero.
    """

    name = 'Damage Aura'
    description = '...'

    # These methods are called when the actual event happens in game

    def unit_attack(self, target, damage):  
        target._health -= (self.level / 100) * damage

    def unit_defend(self, attacker, damage):
        attacker.deal_damage((self.level / 100) * damage)

现在我希望游戏的玩家能够制作自己的英雄,我需要简单。 问题是,我不想仅仅为了让创建英雄更容易而编写“糟糕”的代码。 以下是英雄类的理想外观:

class Warrior(Hero):
    name = 'Warrior'
    description = 'Ancient Warrior is thirsty for blood.'
    maximum_level = 30
    agility = 20
    intelligence = 10
    strength = 30

    class DamageAura(Skill):
        name = 'Damage Aura'
        description = '...'

        def unit_attack(...):
            ...

    class StrongerWeapons(Skill):
        name = 'Stronger Weapons'
        ...

现在的问题是,我希望 name 变量成为实际英雄 (f.e.Warrior) 实例的属性,而不是类变量。 有没有一种简单但安全的方法来合并这两者? 基本上,类变量会定义英雄的默认值,但如果我想创建一个具有自定义名称的 Warrior 实例,我可以通过简单地执行 warrior1 = Warrior(name='Warrior God', maximum_level=40) 来做到这一点

如果我不必担心子类或易于创建,这就是类的样子:

class Hero(object):
    def __init__(self, name, description='', maximum_level=50, skill_set=None, ...):
        self.name = name
        self.description = description
        self.maximum_level = maximum_level
        self.skill_set = skill_set or []
        ...

编辑: 我忘了提;每个玩家都可以扮演完全相同的英雄,在这种情况下是战士,所以这就是为什么战士是一个类,而不仅仅是一个英雄的实例。他们都将拥有相同的技能组合,但具有独特的级别等。

编辑 2: 我对 Python 类或其他任何东西都没有问题,通常我不会制作技能嵌套类或类似的东西,但在这种情况下,我必须在创建类的易用性上投入 很多,所以即使“菜鸟”可以在几乎不知道任何 python 的情况下做到这一点。

【问题讨论】:

  • 不确定您是否在暗示这一点,但__init__ 不是“错误代码”。它很常用。
  • 那么,您打算让玩家通过编写代码来创建自定义英雄类,对吗?如果是,为什么?
  • 请注意,嵌套类在 Python 中很少是个好主意。
  • @Kevin 是的,这就是如果我不必担心子类或易于创建的类的样子。但是,它完全放弃了使用“易于创建”版本的可能性,在该版本中我在类级别定义变量(我原始问题中的第一段代码)。
  • @PieterWitvoet 好吧,从技术上讲,不是玩家,而是服务器主机。我希望每个服务器都能够决定自己的英雄长什么样,这样就可以有数千个不同的英雄拥有不同的技能。

标签: python class variables python-3.x instance


【解决方案1】:

您可以允许最终用户将其Hero 定义创建为字典:

my_hero = dict(name='Warrior'.
               description='Ancient Warrior is thirsty for blood.',
               maximum_level=30,
               ...)

然后您可以轻松创建一个实例,例如:

hero = Hero(**my_hero)

(如果语法不熟悉,请参阅What does ** (double star) and * (star) do for parameters?

对于DamageAuraWarrior,它们似乎分别比SkillHero 的子类更合适


或者,考虑让用户在您的代码之外创建他们的字符(例如,在 JSON、XML、YAML 中...),然后解析文件并从输入数据创建适当的实例。

【讨论】:

  • 阅读我的编辑,我很确定这些类应该是类,而不是实例。不好意思,一开始忘了说。我将如何使用您的方法实施技能?他们需要与英雄相关联,最好先定义英雄,然后再定义技能。
  • @MarkusMeskanen 但是没有理由每个玩家都不能拥有自己的Hero 实例没有 子类化 - 只需从Warrior 规范创建四个Hero 实例.
  • 啊,我现在明白了...谢谢,我想我会使用你的方法!
猜你喜欢
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 2012-01-31
  • 2015-06-09
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多