如何通过while / for循环创建类的许多精确实例(以访问其属性)?

时间:2015-01-14 23:14:01

标签: class object python-3.x pygame instance

我试图使用pygame制作一个atari突破风格游戏,我希望可破坏的块是具有某些属性的对象,我可以随着游戏的进展而改变。 因此我创建了一个" Block" class和后续函数,它循环遍历此类几次,将实例分配给列表。 我遇到的问题是我没有一个独特的名字"对于每个对象,这样就很难访问它们各自的属性。

以下是一个例子:

class Block:
    def __init__(self):
        self.brick = pygame.sprite.Sprite()
        pygame.sprite.Sprite.__init__(self.brick)
        self.brick.image = pygame.Surface([width, height])
        self.brick.image.fill(RED)
        self.brick.rect = self.brick.image.get_rect()
    def blockType (self, hardness):
        self.hardness = hardness  

def lay ():
    layoutm = []
    for x in range (0, 5):
        layoutl = []
        for y in range (0, 12):
            layoutl.append (Block())
        layoutm.append (layoutl)
    return layoutm  

layoutm=lay()

horIndex = -1
for x in range(20, 195, 35):
    horIndex += 1
    verIndex = -1
    for y in range (20, 660, 55):
        verIndex += 1
        #set_trace ()
        brick = (layoutm[horIndex][verIndex]).brick
        brick.rect.topleft = (y,x)
        block_list.add(brick)
        list_of_sprites.add(brick)

你们中的一些人可能会指出我可以简单地从pygame.sprite.Sprite()父类继承,这可能是一个解决方案(太多属性或某些东西)但是由于某种原因,它不适用于我。

layoutm=lay()之后的所有内容都是各个块的位置代码,我包含它的唯一原因是显示我计划如何访问每个相应self.brick的位置属性。可能不是最好的方法,但是构造函数之后的所有方法都是我想要添加到游戏中的功能所必需的(这就是为什么我留在blockType()中来简化问题)。

我的问题基本上是如果我总是必须使用set_trace()之后的代码(运行调试器 pudb 的命令)来访问这些单独的实例。

仅供参考我之所以这么做的原因是因为我计划有一些列表,例如

level_1 = [  
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1]] 

level_2 = [
[0,1,1,2,2,3,3,2,2,1,1,0],
[1,1,2,2,3,3,3,3,2,2,1,1],
[1,2,2,3,3,4,4,3,3,2,2,1],
[1,1,2,2,3,3,3,3,2,2,1,1],
[0,1,1,2,2,3,3,2,2,1,1,0]]

表示级别布局以说明哪种类型的块(当然,代码将被修改为工作。

有时我的术语可能有误(我用法语这个课程),例如混淆实例和对象(我称之为相同,但他们可能不是)所以请随时问我是否事情并不清楚。

1 个答案:

答案 0 :(得分:1)

你的例子似乎有很多事情发生,所以我会告诉你我将如何组织它。我对PyGame没什么经验,所以我会把你的Brick课程的提示留给其他人,但我会尽力帮助你存储砖块。

这就是我定义lay

的方式
def lay():
    return [[Brick() for y in range(12)] for x in range(5)]
layoutm = lay()

此构造称为list comprehension。它比使用"更快#34;并且"追加"而且我觉得它看起来更清晰。它将创建一个包含5个列表的列表,这些列表将表示行。每行包含12个砖。

现在要处理在创建砖块后编辑砖块的属性:

for (row, y) in zip(layoutm, range(20, 195, 35)):
    for (brick, x) in zip(row, range(20, 660, 55)):
        brickSprite = brick.brick
        brickSprite.rect.topleft = (y, x)

这个更多涉及。首先,Python允许您迭代任何可迭代对象中的对象,如下所示:

for num in [0, 1, 2]:
    print(num)

这将打印出值0,1和2.现在,zip是一个函数,它接受两个可迭代对象,并返回一个包含对象对的迭代。例如:

for num_name in zip([0, 1, 2], ["zero", "one", "two"]:
    print(num_name)

这将打印值(0,"零"),(1,"一个")和(2,"两个")。现在回到我的片段:首先,外部循环将迭代每一行及其y坐标。然后,内部循环将迭代该行中的每个砖块及其x坐标。之后,我们可以在砖块上进行操作。

注意我没有在for循环中构建block_list和list_of_sprites。我会使用另一个list comprehension

来做到这一点
block_list      = [brick       for row in layoutm for brick in row]
list_of_sprites = [brick.brick for brick in block_list]

block_list现在应该包含layoutm列表中的每个Brick,list_of_sprites应该包含与每个Brick对应的Sprite。如果您决定将Brick子类化为Sprite类,那么您可以相应地更改它。