Cambiar tipo de disparo

Saludos, estoy probando tipos de disparo para un juego.
Lo que necesito saber es: como hacer para cuando un disparo golpee la estrella cambiar el modo de disparo?
este es el código, basado de algunas respuestas de consultas en este foro.

# coding: utf-8
import pilasengine

class GenerarDisparoDirigido(pilasengine.actores.Actor):
    
    def iniciar(self):
        self.imagen = "invisible.png"
        pass
 
    def actualizar(self):
        actor = pilas.actores.MisilDirigido(self.x, self.y)
        self.eliminar()
        
class MisilDirigido(pilasengine.actores.Actor):
    
    def iniciar(self, x, y):
        self.x = x
        self.y = y
        self.imagen = "disparo_laser.png"
        
        self.dx = (mono.x - self.x) / 10.0
        self.dy = (mono.y - self.y) / 10.0
        self.rotacion = pilas.utils.obtener_angulo_entre(( self.x, self.y), (mono.x, mono.y))
            
    def actualizar(self):
        
        self.x += self.dx
        self.y += self.dy
        
class GenerarDisparoDirigidoDoble(pilasengine.actores.Actor):
    
    def iniciar(self):
        self.imagen = "invisible.png"
        pass
 
    def actualizar(self):
        actor = pilas.actores.MisilDirigido(self.x, self.y, "disparo_laser.png", 15)
        actor = pilas.actores.MisilDirigido(self.x, self.y, "disparo_laser.png", -15)
        self.eliminar()
        
def asignar_arma_doble(estrella, GenerarDisparoDirigidoDoble):
    pin.municion = GenerarDisparoDirigidoDoble
    estrella.eliminar()
    pilas.avisar("ARMA MEJORADA")


def eliminar_estrella(estrella):
    estrella.eliminar()

pilas = pilasengine.iniciar()
pilas.fondos.Tarde()
mono = pilas.actores.Mono()
estrella = pilas.actores.Estrella()

estrella.y = 200
estrella.x = 200
estrella.escala = 0.5
mono.escala = 0.2
mono.y = 200
pin = pilas.actores.Shaolin(y=-248)
pin.aprender("dispararconclick", municion=GenerarDisparoDirigido, frecuencia_de_disparo=3.5 , offset_origen_actor=(20,80))
pin.escala = 0.8    
pilas.colisiones.agregar("estrella", 'MisilDirigido', asignar_arma_doble)
pilas.actores.vincular(GenerarDisparoDirigido)
pilas.actores.vincular(MisilDirigido)
mono.aprender('SeguirAlMouse')
pilas.ocultar_puntero_del_mouse()

pilas.ejecutar()

Hola @Spawn, bienvenido!!!

Te comento una forma de hacer que cambie el disparo: podrías hacer que la función que detecta la colisión entre el disparo y la estrella elimine la habilidad de disparar simple y luego le enseñe la habilidad de disparar doble.

Te paso el código de la función modificado:

def asignar_arma_doble(estrella, disparo):
    pin.eliminar_habilidad("dispararconclick")
    pin.aprender("dispararconclick", municion=GenerarDisparoDirigidoDoble, frecuencia_de_disparo=3.5 , offset_origen_actor=(20,80))
    estrella.eliminar()
    pilas.avisar("ARMA MEJORADA")

Ah, un detalle: esta función recibe dos argumentos que se corresponden con los actores que le especificamos que vamos a colocar. Además, los espera en el mismo orden, por eso cambié la primer linea de la función para que dijera "(estrella, disparo)", ya que el orden de los actores por la llamada que conecta la colisión estaba en ese orden pilas.colisiones.agregar("estrella", 'MisilDirigido', ....

Oh, otras dos cositas que vi mientras probaba el código, cuando se genera un disparo de la clase MisilDirigido parece que hay algunos argumentos de más y da un error. Si cambias la clase GenerarDisparoDirigidoDoble por este código debería evitar funcionar igual:

class GenerarDisparoDirigidoDoble(pilasengine.actores.Actor):
    
    def iniciar(self):
        self.imagen = "invisible.png"
        pass
 
    def actualizar(self):
        actor = pilas.actores.MisilDirigido(self.x - 15, self.y)
        actor = pilas.actores.MisilDirigido(self.x + 15, self.y)
        self.eliminar()

Solo cambié la llamada a MisilDirigido, y agregué ese - 15 y + 15 que aleja un poco los dos disparos laser entre sí.

Lo otro que noté es que a pesar de que no se ven, los disparos parecen crearse en la escena y vivir por siempre… por más que salgan de la ventana los disparos siguen vivos y se empieza a poner un poco lento el juego. Noté que los actores aumentaban pulsando el inspector y viendo el contador de actores en la escena:

Una forma rápida de hacer que la cantidad de cantidad de actores se mantenga baja, y el juego no se ponga lento, es eliminar los actores cuando salen de la pantalla con una habilidad. Podrías asignársela a los lasers luego de crearlos, por ejemplo:

actor = pilas.actores.MisilDirigido(self.x, self.y)
actor.aprender("eliminarseSiSaleDePantalla")

De esa forma, el disparo solamente vivirá mientras esté dentro de la pantalla, una vez que sale se eliminará solo.

¡Abrazo!

Hola Hugo, muchas gracias, conseguí hacer muchos mas modos de disparo, pero no me quedo bien la parte de eliminar el actor, dado a que me devuelve distintos errores, como “VentanaInterprete has no attribute x” y otro el cual me dice que “MisilDirigido” no pertenece a los actores. Desde ya, muchas gracias!