【问题标题】:Can I store items and their properties in an external file and call it when needed? (When programming a Roguelike in Python)我可以将项目及其属性存储在外部文件中并在需要时调用它吗? (在 Python 中编写 Roguelike 时)
【发布时间】:2013-11-24 00:33:23
【问题描述】:

我刚刚通过this tutorial 完成了用 Python 编写 Roguelike 的工作,现在我完全靠自己来弄清楚下一步该去哪里以及该做什么。

我的困境在于代码的混乱。我想在某处存储元素,例如项目;生物;技能;任何可能有大量属性的地方。

目前,所有这些代码都在一个越来越大的文件中,这是最基本的。在关卡上放置物品的函数现在看起来很像这样:(这个函数在关卡生成时被调用)

def place_objects(room):

    #Maximum number of items per room
    max_items = from_dungeon_level([[1, 1], [2, 4]])

    #Chance of each item (by default they have a chance of 0 at level 1, which then goes up)
    item_chances = {}
    item_chances['heal'] = 35
    item_chances['lightning'] = from_dungeon_level([[25, 4]])
    item_chances['fireball'] = from_dungeon_level([[25, 6]])
    item_chances['confuse'] = from_dungeon_level([[10, 2]])
    item_chances['sword'] = from_dungeon_level([[5, 4]])
    item_chances['shield'] = from_dungeon_level([[15, 8]])

    #Choose a random number of items
    num_items = libtcod.random_get_int(0, 0, max_items)

    for i in range(num_items):
        #Choose random spot for this item
        x = libtcod.random_get_int(0, room.x1+1, room.x2-1)
        y = libtcod.random_get_int(0, room.y1+1, room.y2-1)

        #Only place it if the tile is not blocked
        if not is_blocked(x, y):
            choice = random_choice(item_chances)
            if choice == 'heal':
                #Create a healing potion
                item_component = Item(use_function=cast_heal)
                item = Object(x, y, '~', 'Salve', libtcod.light_azure, item=item_component)
            elif choice == 'lightning':
                #Create a lightning bolt scroll
                item_component = Item(use_function=cast_lightning)
                item = Object(x, y, '#', 'Scroll of Lightning bolt', libtcod.light_yellow, item=item_component)
            elif choice == 'fireball':
                #Create a fireball scroll
                item_component = Item(use_function=cast_fireball)
                item = Object(x, y, '#', 'Scroll of Fireball', libtcod.light_yellow, item=item_component)
            elif choice == 'confuse':
                #Create a confuse scroll
                item_component = Item(use_function=cast_confuse)
                item = Object(x, y, '#', 'Scroll of Confusion', libtcod.light_yellow, item=item_component)
            elif choice == 'sword':
                #Create a sword
                equipment_component = Equipment(slot='right hand', power_bonus=3)
                item = Object(x, y, '/', 'Sword', libtcod.sky, equipment=equipment_component)
            elif choice == 'shield':
                #Create a shield
                equipment_component = Equipment(slot='left hand', defense_bonus=1)
                item = Object(x, y, '[', 'Shield', libtcod.sky, equipment=equipment_component)

            objects.append(item)
            item.send_to_back()

因为我打算添加更多项目,所以这个函数会变得很长,所有需要创建的函数来处理每个项目的作用。我真的很想将它从 main.py 中取出并将其存储在其他地方,以使其更易于使用,但我目前不知道如何执行此操作。

以下是我尝试解决问题的尝试:

我可以有一个文件,其中包含一个项目类,其中每个项目包含许多属性; (名称、类型、条件、附魔、图标、重量、颜色、描述、equip_slot、材料)。然后将项目的功能存储在 that 文件中?主文件如何知道何时调用此其他文件?

是否可以将所有项目数据存储在外部文件(如 XML 或其他文件)中并在需要时从那里读取?

显然,我可以应用的不仅仅是物品。当我真正想要的是一个主循环和更好的组织结构时,这对于没有一个非常臃肿的 main.py 非常有用,该文件包含游戏中所有的生物、物品和其他对象膨胀的数千行代码。

【问题讨论】:

    标签: python python-2.7 roguelike libtcod


    【解决方案1】:

    如果您不需要人类可读的文件,请考虑使用 Python 的 pickle 库;这可以序列化对象和函数,这些对象和函数可以写入文件和从文件中读取。

    在组织方面,您可以有一个对象文件夹,将这些类从您的主游戏循环中分离出来,例如:

    game/
        main.py
        objects/
            items.py
            equipment.py
            creatures.py
    

    为了进一步改进,使用继承来做例如:

    class Equipment(Object):
    
    class Sword(Equipment):
    
    class Item(Object):
    
    class Scroll(Item):
    

    然后是任何设置的所有设置,例如剑可以在初始化中定义(例如它在哪只手),并且只需要传入特定剑的变化(例如名称,力量奖励)。

    【讨论】:

      【解决方案2】:

      是否可以将所有项目数据存储在外部文件中(如 XML 或 一些东西)并在需要时从那里读取?

      您可以使用ConfigParser 模块来做到这一点。

      您可以将项目的属性存储在单独的文件(普通的文本文件)中。阅读此文件以自动创建您的对象。

      我将在此处使用文档中的示例作为指南:

      import ConfigParser
      
      config = ConfigParser.RawConfigParser()
      config.add_section('Sword')
      config.set('Sword', 'strength', '15')
      config.set('Sword', 'weight', '5')
      config.set('Sword', 'damage', '10')
      
      # Writing our configuration file to 'example.cfg'
      with open('example.cfg', 'wb') as configfile:
          config.write(configfile)
      

      现在,读取文件:

      import ConfigParser
      from gameobjects import SwordClass
      
      config = ConfigParser.RawConfigParser()
      config.read('example.cfg')
      
      config_map = {'Sword': SwordClass}
      game_items = []
      
      for i in config.sections():
          if i in config_map:
             # We have a class to generate
             temp = config_map[i]()
             for option,value in config.items(i):
                 # get all the options for this sword
                 # and set them
                 setattr(temp, option, value)
             game_items.append(temp)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-11
        • 2019-04-13
        • 1970-01-01
        相关资源
        最近更新 更多