Error al Modularizar Juego

Hola como están!

Hice un juego y se me fue extendiendo mucho código, así que decide modularizarlo en varios archivos.
Y como era de esperar, surgieron algunos inconvenientes.

Uno de los errores ocurre en un archivo que llamé “actor_vaca” y el código es del ejemplo vaca voladora y cuando lo tenía en un solo archivo funcionaba bien.

# -*- encoding: utf-8 -*-

import pilasengine

class Estado:

    def __init__(self, vaca):
        self.vaca = vaca
        self.iniciar()

    def iniciar(self):
        pass



class Ingresando(Estado):

    def iniciar(self):
        self.vaca.definir_animacion([3, 4])
        self.contador = 0
        self.vaca.x = +400
        self.vaca.x = [-170], 2

    def actualizar(self):
        self.contador += 1

        if self.contador > 50:
            self.vaca.estado = Volando(self.vaca)


class Volando(Estado):

    def iniciar(self):
        self.vaca.definir_animacion([3, 4])

    def actualizar(self):
        velocidad = 5
		

        if self.pilas.escena.control.arriba:
            self.vaca.y += velocidad
        elif self.pilas.escena.control.abajo:
            self.vaca.y -= velocidad

        if self.vaca.y > 210:
            self.vaca.y = 210
        elif self.vaca.y < -210:
            self.vaca.y = -210


class Perdiendo(Estado):

    def iniciar(self):
        self.vaca.definir_animacion([0])
        self.vaca.centro = ('centro', 'centro')
        self.velocidad = -2

    def actualizar(self):
        self.vaca.rotacion += 7
        self.vaca.escala += 0.01
        self.vaca.x -= self.velocidad
        self.velocidad += 0.2
        self.vaca.y -= 1


class Vaca(pilasengine.actores.Actor):


    def iniciar(self):
        self.grilla = self.pilas.imagenes.cargar_grilla('data/sprites.png', 5, 1)
        self.imagen = self.grilla
        self.definir_animacion([0])
        self.centro = (140, 59)
        self.radio_de_colision = 40
        self.x = -170
        self.estado = Ingresando(self)
        self.contador = 0

    def definir_animacion(self, cuadros):
        self.paso = 0
        self.contador = 0
        self.cuadros = cuadros

    def actualizar(self):
        self.estado.actualizar()
        self.actualizar_animacion()

    def actualizar_animacion(self):
        self.contador += 0.2

        if (self.contador > 1):
            self.contador = 0
            self.paso += 1

            if self.paso >= len(self.cuadros):
                self.paso = 0

        self.imagen.definir_cuadro(self.cuadros[self.paso])

    def perder(self):
        self.estado = Perdiendo(self)
        self.t = self.pilas.actores.Texto("Sigue intentando...")
        self.t.escala = 0
        self.t.escala = [1], 3.5

El error que me sale dice:

ERROR: "AttributeError("Volando instance has no attribute ‘pilas’)

Y me detalla la linea 41 "if self.pilas.escena.control.arriba:
Y linea 86 “self.estado.actualizar()”

Hola @Fabian_Montecino, lo que sucede es que el objeto de la clase “Estado” no tiene un atributo llamado “pilas”.

Para resolverlo, deberías enviarle el objeto “pilas” al momento de crear el objeto.

Por ejemplo, yo lo haría de esta forma: agregaría un parámetro más a la clase Estado:

class Estado:

    def __init__(self, pilas, vaca):
        self.vaca = vaca
        self.pilas = pilas
        self.iniciar()

    def iniciar(self):
        pass

y luego, cada vez que hago un cambio de estado me encargo de re-enviarle el objeto pilas. Por ejemplo, en el objeto Vaca, cuando inicia, utilizaría esto:

self.estado = Ingresando(self.pilas, self)

Ah, por cierto, tal vez te resulte raro que los actores, escenas y módulos internos de pilas tienen este atributo “self.pilas”, pero otros objetos estándar de python no, y halla que re-enviarles el objeto a mano… esto es algo que implementé para que podamos usar actores u escenas sin argumentos y evitar que “pilas” no termine siendo una variable global. Hay un artículo explicando algunos de estos detalles por acá:

http://www.examplelab.com.ar/la-renovacion-de-pilas-engine/

Hola @hugoruscitti, gracias por responder!. Modifiqué como me sugeriste, pero sigo teniendo errores.

Ahora es en la clase Ingresando: AttributeError “Ingresando instance has no attribute ‘definir_animacion’”

Y me da error en self.iniciar() de la clase “Estado”
self.estado.actualizar() de la clase “Vaca”
self.Vaca.estado = Volando(self.vaca, self)

No se si tengo que agregarle parámetros a todas las clases, o no le estoy pasando los argumentos a los objetos que crean.

Perdón por las molestias pero te envié un mail con otras dudas. Y si queres te envío el juego completo con todos los archivos.

Hola @Fabian_Montecino, tendrías que tener en cuenta que al momento de crear el objeto Volando siempre reciba a pilas como primer argumento y la vaca como segundo, porque esa clase “Volando” va a usar el método “init” que te pasé antes.

Si querés reenviame el código completo y lo miro, pero recién en unos días porque estoy algo tapado de trabajo :grin:

Abrazo!

Ok, te envío al mail el código completo. Cuando puedas lo ves y de paso me dices que te parece el juego.

Abrazo!