关于python:基于Django的技能实现

Django-based skill implementation

我正在使用 django 开发 RPG,并且正在考虑实施部分技能系统的不同选项。

假设我有一个基础技能课程,例如:

1
2
3
4
class Skill (models.Model):
      name = models.CharField()
      cost = models.PositiveIntegerField()
      blah blah blah

实施特定技能的方法有哪些?想到的第一个选项是:

1) 每个技能都扩展了技能等级和
覆盖特定函数:

不确定这将如何在 django 中工作。似乎为每个技能都有一个数据库表会有点过头了。子类可以是抽象的,而技能类有一个条目吗?听起来不对。使用代理类怎么样?

还有哪些其他选择。我想避免纯 django 方法的脚本方法。


也许你可以考虑将一个技能和它的相关效果分开。更有可能的是,技能最终会产生一种或多种与之相关的效果,并且该效果可能会被多种技能使用。

例如,一个效果可以是"对当前目标造成 N 点冰霜伤害"。该效果可以被技能"暴雪之箭"、"冰霜冲击"和"冰霜新星"使用。

models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Skill(models.Model):
    name = models.CharField()
    cost = models.PositiveIntegerField()
    effects = models.ManyToManyField(Effect)

class Effect(models.Model):
    description = models.CharField()
    action = models.CharField()

    # Each Django model has a ContentType.  So you could store the contenttypes of
    # the Player, Enemy, and Breakable model for example
    objects_usable_on = models.ManyToManyField(ContentType)

    def do_effect(self, **kwargs):
        // self.action contains the python module to execute
        // for example self.action = 'effects.spells.frost_damage'
        // So when called it would look like this:
        // Effect.do_effect(damage=50, target=target)
        // 'damage=50' gets passed to actions.spells.frost_damage as
        // a keyword argument    

        action = __import__(self.action)
        action(**kwargs)

效果\\\\\\\\spells.py

1
2
3
4
5
6
def frost_damage(**kwargs):
    if 'damage' in kwargs:
        target.life -= kwargs['damage']

        if target.left <= 0:
            # etc. etc.


当我看到这个时,有两个类:一个是作为抽象实例的技能(例如说瑞典语的技能,Excel 开发的技能),然后是一个人所拥有的实际技能技能的外键。


我会设置一些继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BaseSkill(models.Model):
    name = models.CharField()
    cost = models.PositiveIntegerField()
    type = models.CharField()
    ....

class FireSkill(BaseSkill):
    burn_time = models.PositiveIntegerField()

    def save():
        self.type = 'fire_skill'
        return super(FireSkill, self).save()

class IceSkill(BaseSkill):
    freeze_time = models.PositiveIntegerField()

    def save():
        self.type = 'ice_skill'
        return super(IceSkill, self).save()

这样做的好处是,当您只想列出所有需要使用 BaseSkill 类的玩家技能时。如果 vendor正在销售技能,您只需列出 BaseSkill 类的价格。当您需要更详细的技能属性时,可以轻松获取类型来访问它。例如。如果你有:skill = BaseSkill.objects().get(pk=1) 你可以通过 Skill.ice_skill.freeze_time 或者更一般的 get_attribute(skill, Skill.type).field_name

来访问冰技能


我有点累(在瑞典迟到了),所以如果我误解了我很抱歉,但我首先想到的是多对多关系的额外字段。


您还可以使用单个表并将基于对象的内部模型保存在腌制字段中。