while programacion for ejercicios ejemplos ciclo class object python-3.x pygame instance

class - programacion - for en python 3



¿Cómo creo muchas instancias precisas de una clase(para acceder a sus atributos) a través de un ciclo while/for? (1)

Intento hacer un juego de estilo atari breakout usando pygame, y quiero que los bloques frágiles sean objetos con ciertos atributos que puedo cambiar a medida que avanza el juego. Como tal, creé una clase "Bloque" y una función posterior que recorre esta clase varias veces asignando las instancias a una lista. El problema que encontré es que no tenía un "nombre" distinto para cada objeto, por lo que era difícil acceder a sus atributos individuales.

Aquí hay un ejemplo:

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)

Algunos de ustedes pueden señalar que simplemente puedo heredar de la clase padre pygame.sprite.Sprite() y que podría ser una solución (demasiados atributos o algo así) pero por alguna razón eso no me funcionaba.

Todo después del layoutm=lay() es el código posicional para los respectivos Bloques y la única razón por la que lo incluí es para mostrar cómo estaba planeando acceder a los atributos de posición de cada uno de los respectivos self.bricks. Probablemente no sea la mejor manera de hacerlo, pero todos los métodos que vienen después del constructer son necesarios para las funciones que pretendo agregar al juego (por eso lo dejé en blockType () para simplificar el problema).

Mi pregunta es, básicamente, si siempre tengo que usar el código que viene después de set_trace() (que es el comando para ejecutar el depurador pudb ) para acceder a estas instancias individuales o no.

Solo para obtener información: la razón por la que reviso todo esto es porque planeo tener algunas listas como

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]]

representando el diseño de nivel para decir qué tipo de bloque se fue (el código se modificará para que funcione, por supuesto).

TAMBIÉN mi terminología puede estar equivocada algunas veces (estoy tomando esta clase en francés), como instancias confusas y objetos (los llamo igual pero probablemente no lo sean), así que siéntete libre de preguntarme si algo no está claro.


Tu ejemplo parece tener mucho en juego, así que te mostraré cómo lo habría organizado. Tengo poca experiencia con PyGame, así que dejaré los consejos para su clase Brick a otros, pero intentaré ayudar con el almacenamiento de Ladrillos.

Así es como yo habría definido lay :

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

Esta construcción se llama una lista de comprensión . Es más rápido que usar "para" y "agregar" y creo que se ve más claro. Creará una lista que contiene 5 listas, que representarán las filas. Cada una de las filas contendrá 12 Ladrillos.

Ahora, para tratar con la edición de los atributos de los ladrillos después de que se hayan creado:

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)

Este es un poco más complicado. En primer lugar, Python le permite iterar sobre los objetos en cualquier objeto iterable, así:

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

Esto imprimirá los valores 0, 1 y 2. Ahora, zip es una función que toma dos objetos iterables, y devuelve un iterable que contiene pares de los objetos. Por ejemplo:

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

Esto imprimirá los valores (0, "cero"), (1, "uno") y (2, "dos"). Ahora vuelvo a mi fragmento: primero, el ciclo externo iterará sobre cada fila y su coordenada y. Luego, el ciclo interno iterará sobre cada bloque en esa fila y su coordenada x. Después de eso, podemos realizar operaciones en los ladrillos.

Tenga en cuenta que no construí el block_list y list_of_sprites en los bucles for. Lo haría usando otra lista de comprensión :

block_list = [brick for row in layoutm for brick in row] list_of_sprites = [brick.brick for brick in block_list]

block_list ahora debe contener cada Brick en la lista layoutm y list_of_sprites debe contener los Sprites correspondientes a cada Brick. Si decide hacer de la subclase Brick la clase Sprite, puede cambiar esto en consecuencia.