2014-01-14 8 views
0

Для контекста я работаю над системой инвентаризации в RPG, и я прототипирую ее с помощью кода python.Создание динамических переменных для класса из класса

Я не понимаю, как сделать отдельные переменные для каждого экземпляра элемента без объявления их вручную. В качестве короткого примера:

class Player(object): 
    def __init__(self): 
     self.Items = {} 

class Item(object): 
    def __init__(self): 
     self.Equipped = 0 

class Leather_Pants(Item): 
    def __init__(self): 
     #What do i place here? 
    def Pick_Up(self, owner): 
     owner.Items[self.???] = self #What do i then put at "???" 
    def Equip(self): 
     self.Equipped = 1 
PC = Player() 
#Below this line is what i want to be able to do 
Leather_Pants(NPC) #<-Create a unique instance in an NPC's inventory 
Leather_Pants(Treasure_Chest5) #Spawn a unique instance of pants in a treasure chest 
Leather_Pants1.Pick_Up(PC) #Place a specific instance of pants into player's inventory 
PC.Items[Leather_Pants1].Equip() #Make the PC equip his new leather pants. 

Если я сделал что-то глупо в приведенном выше коде, укажите его.

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

Я не против, если я должен использовать другой класс или функцию для него, как «Create_Item (Leather_Pants(), Treasure_Chest3)»

Какой самый лучший способ пойти об этом, или если вы думаете, что я» т. е. все это неправильно, каким образом было бы более правильным?

+0

Когда вы вводите 'Leather_Pants1', определив два объекта' Leather_Pants', какой из них вы хотите? И почему? Каково правило? – abarnert

+0

Не имеет значения, начинается ли мой индекс с 1 или 0. Но скажем, что это второй (т. Е. Тот, что у Treasure_Chest5) – Cestarian

+1

В качестве побочного примечания: Возможно, вам стоит сначала рассмотреть игру на языке, например [Inform ] (http://inform7.com), разработанный специально для такого рода вещей, и имеет встроенные библиотеки для вещей, таких как одежда, npcs, инвентарь, сундуки. Это облегчает игру с более гибкими деталями вашего дизайна, а затем, когда вам будет удобно, вы можете попробовать реализовать тот же дизайн в Python. – abarnert

ответ

5

Как правило, you don't want to create dynamic variables, и вы хотите keep data out of your variable names.

Вместо того, чтобы создавать переменные с именем pants0, pants1 и т. Д., Почему бы не просто создать, скажем, один список всех кожаных штанов? Затем вы просто делаете pants[0], pants[1] и т. Д. И ни одна из других частей вашего кода не должна знать ничего о том, как штаны хранятся. Поэтому все ваши проблемы исчезают.

И, тем не менее, вы, вероятно, не хотите создавать Leather_Pants, чтобы автоматически добавлять себя в глобальную среду. Просто назначьте это нормально.

Итак:

pants = [] 
pants.append(Leather_Pants(NPC)) 
pants.append(Leather_Pants(chests[5])) 
pants[1].pickup(PC) 

Брюки не должны знать, что они # 1. Всякий раз, когда вы вызываете метод на них, у них есть аргумент self, который они могут использовать. И элементам игрока не нужно сопоставлять какое-либо произвольное имя каждому элементу; просто сохраните элементы непосредственно в списке или установите. Например:

class Player(object): 
    def __init__(self): 
     self.Items = set() 

class Item(object): 
    def __init__(self): 
     self.Equipped = 0 

class Leather_Pants(Item): 
    def __init__(self): 
     pass # there is nothing to do here 
    def Pick_Up(self, owner): 
     self.owner.Items.add(self) 
    def Equip(self): 
     self.Equipped = 1 
+0

Я знаю, что я должен как правило избегать динамических переменных, это первый раз, когда я думал, что на самом деле они им нужны. Думаю, я смогу сделать это как список, позвольте мне попробовать. Также, что вы подразумеваете под set()? я никогда не видел этого до – Cestarian

+1

, что же отправить? в вашем примере, как я могу создать экземпляр Leather_Pants? – Cestarian

+0

Я понял, что могу использовать «pants.append (Leather_Pants())», как в вашем первом примере, чтобы создать экземпляр. Но я до сих пор не знаю, что такое отправка: O – Cestarian

1

Abernat решил несколько вопросов, но я думал, что взвешиваю еще несколько.

Вы, кажется, используете ООП, но смешиваете несколько проблем с вашими объектами. Например, моим штанам все равно, если они носят или нет, мне все равно, по целому ряду причин. С точки зрения питона Pants класс не должен отслеживать, является ли она оборудована (только что Экипирующие), то Player класс должен:

class CarryableItem: 
    isEquipable = False 
class Pants(CarryableItem): 
    isEquipable = True  

class Player: 
    def __init__(self): 
    self.pants = None # Its chilly in here 
    self.shirt = None # Better take a jumper 
    self.inventory = [] # Find some loot 
    def equip(self,item): 
    if is.isEquipable: 
     pass # Find the right slot and equip it, 
      # put the previously equipped item in inventory, etc... 

Кроме того, его очень редко, что предмет нужно будет знать, кто его владелец или что его схватили, так как глаголы, которые снова должны идти на плеер:

class Player: 
    maxCarry = 10 
    def take(Item): 
    if len(inventory) < maxCarry: 
     inventory.append(item) 

Наконец, хотя мы пытались переместить большинство глаголов на актеров, которые на самом деле сделать что-то, иногда это не всегда случай.Например, когда инстанцировании грудь:

import random 
class StorageItem: 
    pass 
class Chest(StorageItem): 
    __init__(self): 
    self.storage = random.randint(5) 
    self.loot = self.spawnLoot() 
    def spawnLoot(self): 
    for i in range(self.storge): 
     # Lets make some loot 
     item = MakeAnItem # Scaled according to type level of dungeon, etc. 
     loot.append(item) 
    def remove(item): 
    self.loot[self.loot.index(item)]=None 

Теперь вопрос о том, что делать, когда игрок хочет грабить грудь?

class Player: 
    def plunder(storage): 
    for item in storage.loot: 
     # do some Ui to ask if player wants it. 
     if item is not None and self.wantsItem(item) or \ 
      (self.name="Jane" and self.wantsItem(item) and self.doesntWantToPay): 
     self.take(item) 
     storage.remove(item) 

редактировать: Ответ на комментарий:

Если Вам интересно о расчете класса брони, или тому подобное, что снова является фактором пользователя, а не вещь. Например:

class Player: 
    @property 
    def clothing(self): 
    return [self.pants,self.top] 
    @property 
    def armorClass(self): 
    ac = self.defence 
    for item in self.clothing: 
     def = item.armorClass 
     if self.race="orc": 
      if item.material in ["leather","dragonhide"]: 
      def *= 1.5 # Orcs get a bonus for wearing gruesome dead things 
     elif item.material in ["wool","silk"]: 
      def *= 0.5 # Orcs hate the fineries of humans 
     ac += def 
    return ac 
pants = Pants(material="leather") 
grum = Player(race="orc") 
grum.equip(pants) 

print grum.armorClass 
>>> 17 # For example? 
+0

Элемент не обязательно должен знать, что он экипирован или нет в вашем коде, но что, если он оказывает влияние на пользователя (например, броня дает класс +10 брони) – Cestarian

+0

@Cestarian Я добавил редактирование вокруг вашего вопроса. Опять эффект действует на игрока, а не на элемент, который остается статичным. –

+0

def = item.armorClass? – Cestarian

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