2009-12-03 4 views
3

Я работаю над RPG с помощью Django, и я рассматриваю различные варианты реализации части системы навыков.Django на основе реализации навыков

Скажем, у меня есть класс ИЭ базовый навык, что-то вроде:

class Skill (models.Model): 
     name = models.CharField() 
     cost = models.PositiveIntegerField() 
     blah blah blah 

Что бы некоторые подходы к реализации конкретных навыков? Первый вариант, который приходит на ум:

1) Каждый навык увеличивает навык класса и переопределяет специфические функции:

Не уверен, как это будет работать в Джанго. Кажется, что наличие таблицы db для каждого навыка будет излишним. Может ли дочерний класс быть абстрактным, в то время как класс Skill имеет запись? Звучит не так. Как насчет использования прокси-класса?

Что некоторые другие варианты. Я бы хотел избежать сценария подхода для чистого подхода джанго.

+2

Насколько уникальным является каждый навык от одного к другому? У некоторых есть поля, уникальные для особого навыка? – Carson

ответ

5

Может быть, вы могли бы рассмотреть отделяя мастерство и это связано эффект. Скорее всего, навыки будут иметь один или несколько эффектов, связанных с ними, и этот эффект потенциально может быть использован несколькими навыками.

Например, эффект может быть «Имеет ли N ущерб от заморозков к текущей цели». Этот эффект может быть использован навыками «Blizzard Bolt», «Frost Blast» и «Icy Nova».

models.py

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

def frost_damage(**kwargs): 
    if 'damage' in kwargs: 
     target.life -= kwargs['damage'] 

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

В играх, над которыми я работал, у вас не будет отдельного подкласса для каждого навыка. У вас будет что-то вроде этого с универсальным классом «Skill», который держит универсальную информацию и ассоциирует различные эффекты и действия с навыками по мере необходимости. – Kylotan

+0

(Это должно было быть комментарий «Я согласен с этим ответом».) – Kylotan

+0

Спасибо за хороший ответ. Я знал, что в конечном итоге сделаю кучу наследования для других типов навыков, то есть пассивных против активных навыков и т. Д. Имея отдельное поле как часть базового навыка, указывающего на модуль/класс/функцию, определяющую навык/эффект конкретные действия доходят до сути того, что я пытался выяснить. – awithrow

1

Я устал (поздно здесь, в Швеции), поэтому я сожалею, если не понял, но первое, что появилось в моей голове, было extra fields on many-to-many relationships.

+0

Это отличное предложение, но мне сложно думать о том, как избежать использования дополнительных моделей для каждого навыка с помощью этого метода. – jathanism

1

Я бы установить некоторое наследство.

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. Если продавец продает навыки, вам нужно всего лишь перечислить цены из класса BaseSkill. Когда вам нужны более подробные атрибуты умения, легко получить тип для доступа к нему. Например. Если у вас есть:. Умение = BaseSkill.objects() получим (рк = 1) вы можете получить доступ льда мастерство, делая skill.ice_skill.freeze_time или в более общем get_attribute (умение, skill.type) .field_name

1

Когда я видел это, был два класса: один для Skill как абстрактный экземпляр (например, умение говорить по-шведски, умение в развитии Excel), а затем фактические навыки, которыми обладают лицом с иностранным ключ к навыку.

0

Вы также можете использовать одну таблицу и сохранить на основе от объекта внутренней модели в квашеной поле.

Смежные вопросы