Blog
A partir de este momento, tendremos que realizar unos cambios a nuestro juego. Debido a que el código expuesto anteriormente, sí que nos permite ejecutar nuestro juego correctamente pero tiene un par de deficiencias.
Estas deficiencias se destacan a que nuestro código puede mantenerse y hacer que nuestro juego escale a futuro (si le queremos hacer cambios, como agregarle nuevos enemigos, un sistema de niveles, entre otras cosas que se nos ocurra agregar), pero será un poco más difícil debido a que el esquema que mantenemos es un esquema funcional.
A partir de este momento pasaremos de un esquema funcional a un esquema totalmente diferente, este esquema será el de programación orientada a objetos. Así es como deben esta programados la mayoría de nuestras aplicaciones o cualquier otra cosa que estemos programando.
La importancia de todo esto es que permite a tu código que sea más escalable y que pueda ser leído de una manera mucho más fácil por otros programadores.
Antes de comenzar quiero decirte que estaremos cargando archivos y obteniendo directorios que no usaremos aún, así que no te preocupes que los usaremos más adelante, esto lo hago para ir ahorrando tiempo, de igual forma en el código estará comentado.
Vamos a comenzar escribiendo el mismo juego pero con el esquema de la programación orientada a objetos, voy a crear un nuevo archivo llamado game.py y le agregaremos el siguiente código:
import pygame, sys from pygame.locals import * import os import random ANCHO = 750 ALTO = 800 os.environ['SDL_VIDEO_CENTERED'] = '1' # Centramos la ventana de nuestro juego al centro de nuestra pantalla # Ahora crearemos el objeto para nuestra nave espacial. class naveEspacial(pygame.sprite.Sprite): DISPARO_DELAY = 30 # Para poder tener un tiempo intermedio entre cada disparo NAVE = os.path.join('assets', 'nave1.png') # Cargamos la imagen de nuestra nave SHOOT = os.path.join('assets', 'shoot.wav') # Obtenemos el directorio del sonido del disparo def __init__(self): super().__init__() # Llamamos al constructor de la super clase que en este caso es una clase propia de pygame de la que estamos heredando self.nave_img = pygame.image.load(self.NAVE) self.cuerpo = self.nave_img.get_rect() self.cuerpo.centerx = ANCHO/2 # Posicionamos nuestra nave en X a la mitada del ancho de la pantalla al iniciarse el juego self.cuerpo.centery = ALTO-45 # Posicionamos nuestra nave en Y en el alto de la pantalla - 45px al iniciarse el juego self.listaDisparo = [] # Creamos esta lista que más adelante nos servirá para nuestra nave dispare self.velocidad_movimiento = 4 # Creamos la velocidad de movimiento de nuestra nave self.bonificacion = False # Creamos esta variable que nos servira para identificar si la bonificación del bonus está activa. self.contador_regresivo = 0 # Esta variable nos permitira establecer un enfriamiento en el disparo de nuestra nave # Creamos el método para que nuestra nave se dibuje sola def dibujar(self, superficie): superficie.blit(self.nave_img, self.cuerpo) # Ahora creamos el método que delimitará el movimiento para que nuestra nave no se salga de las dimensiones de nuestra ventana de juego def delimitar_movimiento(self): if self.cuerpo.left <= 0: self.cuerpo.left = 0 elif self.cuerpo.right >= 750: self.cuerpo.right = 750 elif self.cuerpo.top <= 0: self.cuerpo.top = 0 elif self.cuerpo.bottom >= 800: self.cuerpo.bottom = 800 # Lo que sige es crear nuestro objeto Nube class Nube(pygame.sprite.Sprite): NUBE = os.path.join('assets', 'nube2.png') # Obtenemos el directorio de la imagen de nuestra nube def __init__(self, posx, posy): super().__init__() self.nube_img = pygame.transform.scale((pygame.image.load(self.NUBE)), (random.randint(75,150), random.randint(85, 90))) # Cargamos la imagen de nuestra nube y con random.randint establecemos un ancho y un largo de forma aleatoria para nuestra nube self.cuerpo = self.nube_img.get_rect() # Obtenemos el rectangulo de la imagen de nuestra nube a la que hemos llamado cuerpo para hacer referencia al cuerpo de la nube self.velocidad_nube = 1 # asignamos una velocidad self.cuerpo.left = posx # asignamos un posicionamiento en el eje x self.cuerpo.top = posy # # asignamos un posicionamiento en el eje y # Creamos el método de la trayectoria de la nube para que esta se mueve desde arriba hacia abajo def trayectoria(self): self.cuerpo.top = self.cuerpo.top + self.velocidad_nube # Creamos el método dibujar para que nuestra nube se dibuje sola def dibujar(self, superficie): superficie.blit(self.nube_img, (self.cuerpo.left, self.cuerpo.top)) # Ahora creamos el objeto Misil class Misil(pygame.sprite.Sprite): MISIL = os.path.join('assets', 'misil1.png') # Nuevamente obtenemos el directorio para nuestra imagen, en este caso el misil. EXPLOSION = os.path.join('assets', 'explosion1.png') def __init__(self, posx, posy): super().__init__() # Creamos todos los atributos de nuestro misil como lo hicimos con las dos clases anteriores self.misil_img = pygame.transform.scale((pygame.image.load(self.MISIL)), (random.randint(30,40), random.randint(50, 70))) self.cuerpo_misil = self.misil_img.get_rect() self.velocidad_min = 1 # Establecemos una velocidad minima del misil self.velocidad_max = 3 # Estabblecemos una velocidad máxima del misil self.velocidad_misil = random.randint(self.velocidad_min, self.velocidad_max) # Le enviamos como argumento al randint la velocidad minima del misil y la velocidad máxima, para que establezca una velocidad aleatoria al misil al momento de ser creado y esto hará que algunos misiles vayan más rápido que otros self.cuerpo_misil.left = posx # Posición en el eje X self.cuerpo_misil.top = posy # Posición en el eje Y #Misil destruido self.misil_dest = pygame.transform.scale((pygame.image.load(self.EXPLOSION)), (30,40)) # Imagen para la animación del misil destruido self.cuerpo_misil_dest = self.misil_dest.get_rect() # Cuerpo del misil al ser destruido # Método trayectoria para que nuestro misil se desplace de arriba a abajo def trayectoria(self): self.cuerpo_misil.top = self.cuerpo_misil.top + self.velocidad_misil # Método dibujar para que nuestro misil se dibuje solo def dibujar(self, superficie): superficie.blit(self.misil_img, (self.cuerpo_misil.left, self.cuerpo_misil.top)) # Creamos una función llamada juego que es donde instanciaremos parte de la lógica y lo que se mostrará en nuestro juego y recibirá una variable llamada record = None, esto nos permitirá identificar si el esta comenzando por primera vez o estamos repitiendo el juego porque perdimos anteriormente. def juego(record=None): pygame.init() VENTANA = pygame.display.set_mode((ANCHO, ALTO)) pygame.display.set_caption('Unipython - InvaSion') FONDO = os.path.join('assets', 'fondo.jpg') fondo_ventana = pygame.transform.scale(pygame.image.load(FONDO), (ANCHO, ALTO)) # Usamos pygame.transform.scale para que el fondo pueda adaptarse al tamaño de la pantalla jugador = naveEspacial() iniciar = True # Variable para determinar cuando se inicia o se sale del juego, mientras sea True el juego se ejecutara y cuando cambie a False el juego se cerrará # Establecemos los FPS y el reloj que tomará mas adelante esos FPS como parámetro FPS = 80 clock = pygame.time.Clock() # Propiedades para el record y los puntos puntos = 0 # Con la siguiente lógica detectamos si se esta repitiendo una vez más el juego para que así guarde el puntaje que se obtuvo en la partida anterior if record == None: record = 0 else: record = record perdiste = False # Variable que indica si el jugador perdió o no # Propiedades para las nubes cantidad_nubes = [] contador_nubes = 0 # Propiedades para los misiles cantidad_misiles = [] contador_misiles = 0 cantidad_misiles_destruidos = [] # Esta lista la usamos para poder realizar la animación de explosión de los misiles contador_misiles_destruidos = [] # Propiedad para el bonus contador_bonus = 0 # Establece cada cuanto se genera la instancia de un bonus cantidad_bonus = [] # Guarda los bonus que se van creando duracion_bonus = 0 # Establece cuanto dura el bonus cuando el jugador lo consume caida_bonus = 1800 # Establece cada cuanto aparece el bonus en la pantalla de nuestro juego = 0 # Fonts texto_enjuego = pygame.font.SysFont('Times New Roman', 30, bold=2) # Texto que aparecerá mientras jugamos texto_empezar = pygame.font.SysFont('Times New Roman', 30, bold=2) # Texto que aparecerá en la pantalla de espera texto_titulo = pygame.font.SysFont('Times New Roman', 60, bold=6) # Texto que aparecerá en la pantalla de espera en letras más grandes # Creamos una función para crear una pantalla de espera en nuestro juego def fondo_espera(): while True: # Dibujar texto dentro de nuestra ventana empezar = texto_empezar.render('Presione cualquier tecla para comenzar', 1, (255,255,255)) titulo = texto_titulo.render('Unipython InvaSion', 1, (255,255,255)) VENTANA.fill((0,0,0)) VENTANA.blit(empezar, (80,400)) VENTANA.blit(titulo, (80, 320)) pygame.display.update() for evento in pygame.event.get(): if evento.type == pygame.QUIT: pygame.quit() if evento.type == pygame.KEYDOWN: if evento.key == pygame.K_ESCAPE: # Quita el juego al presionar ESCAPE pygame.quit() return fondo_espera() # Ponemos en marcha nuestra función # Guardamos la ubicación de los sonidos en las siguientes variables MUSICA_FONDO = os.path.join('assets', 'musicajuego.mp3') FIN_JUEGO = os.path.join('assets', 'juegoterminado.wav') MISIL_DESTRUIDO = os.path.join('assets', 'destruido.wav') # Cargamos la musica de fondo y la reproducimos pygame.mixer.music.load(MUSICA_FONDO) pygame.mixer.music.set_volume(0.1) pygame.mixer.music.play() # Cargamos los sonidos para poder reproducirlos luego juego_terminado = pygame.mixer.Sound(FIN_JUEGO) misil_destruido = pygame.mixer.Sound(MISIL_DESTRUIDO) while iniciar: if perdiste == False: puntos += 0.1 _puntos = "{0:.0f}".format(puntos) # Formateamos los puntos para no mostrar decimales por pantalla en el juego # Llamamos al método que delimita el movimiento jugador.delimitar_movimiento() # Ahora, haremos posible que podamos mover nuestra nave con el mouse con el siguiente código for evento in pygame.event.get(): if perdiste == False: if evento.type == MOUSEMOTION: # Si se mueve el ratón, este se mueve adonde el cursor esté. jugador.cuerpo.move_ip(evento.pos[0] - jugador.cuerpo.centerx, evento.pos[1] - jugador.cuerpo.centery) # A partir de este punto, haremos posible que nuestra nave se pueda mover con las teclas a,w,s,d y las flechas del teclado if perdiste == False: teclas = pygame.key.get_pressed() # Inicia una instancia que detecta las teclas que se pulsan if teclas[pygame.K_a] or teclas[pygame.K_LEFT]: jugador.cuerpo.left -= jugador.velocidad_movimiento if teclas[pygame.K_d] or teclas[pygame.K_RIGHT]: jugador.cuerpo.right += jugador.velocidad_movimiento if teclas[pygame.K_w] or teclas[pygame.K_UP]: jugador.cuerpo.top -= jugador.velocidad_movimiento if teclas[pygame.K_s] or teclas[pygame.K_DOWN]: jugador.cuerpo.bottom += jugador.velocidad_movimiento VENTANA.blit(fondo_ventana, (0,0)) # Creamos una sentencia que siempre sea True para sumar + 1 el contador if True: contador_misiles += 1 # Cuando el contador llegue a 50 añadiremos 1 nube y reniciamos el contador a 0 nuevamente para que constantemente se repita este ciclo gracias al bucle while. if contador_misiles == 50: contador_misiles = 0 ejex = random.randint(0, 580) # Le damos una posición en x aleatoria al misil misil = Misil(ejex, -100) cantidad_misiles.append(misil) # Dibujamos cada misil y llamamos a su trayectoria para que se muevan hacia abajo for misil in cantidad_misiles: misil.dibujar(VENTANA) if perdiste == False: misil.trayectoria() # Creamos una sentencia que siempre sea True al igual como hicimos con los misiles if True: contador_nubes += 1 if contador_nubes == 40: contador_nubes = 0 ejex = random.randint(0, 650) # Le damos una posición en x aleatoria a la nube nube = Nube(ejex, -100) cantidad_nubes.append(nube) # Agregamos cada nube a la lista # Dibujamos cada nube y llamamos a su trayectoria para que se muevan hacia abajo. for nube in cantidad_nubes: nube.dibujar(VENTANA) if perdiste == False: nube.trayectoria() # Eliminamos las nubes que lleguen al final de la pantalla # Imprimimos los textos puntos y record en pantalla texto_puntos = texto_enjuego.render('Puntos:{}'.format(_puntos), 1, (151,151,151)) texto_record = texto_enjuego.render('Record:{}'.format(record), 1, (151,151,151)) VENTANA.blit(texto_puntos, (10,10)) VENTANA.blit(texto_record, (10,50)) jugador.dibujar(VENTANA) # Dibujamos el jugador clock.tick(FPS) pygame.display.update() if perdiste == True: record = _puntos # Cuando perdamos los puntos obtenidos en dicha partida, se guardarán en la variable record juego(record) # Acá llamamos nuevamente a la función de nuestro juego, la cual recibe el record y ejecutará la pantalla de espera. Cuando el jugador pulse cualquier tecla para volver a jugar, podrá ver en la pantalla la palabra record con el puntaje que obtuvo en la partida pasada donde perdió juego()
Muy bien, hasta ahora ya tenemos el mismo juego que anteriormente habíamos programado con el esquema de la programación funcional, pero que ahora hemos llevado al esquema de la programación orientada a objetos.
Es importante mencionar que le hemos hecho los siguientes cambios a nuestro juego:
• Ahora los misiles se mueven un poco más rápido
• La puntuación se suma mucho más lento
• Hemos cambiado la imagen de las nubes
Agregando nuevas funciones a nuestro juego
A partir de este punto debemos hacer que nuestro juego comience a escalar, para este caso agregaremos algunas funcionalidades.
Por ejemplo, haremos que nuestra nave pueda disparar, cada x tiempo aparezca un bonus que si lo cogemos nuestra nave disparará más rápido por 20 segundos y además cada vez que este bonus vaya apareciendo aumentará su tiempo para que vuelva a aparecer nuevamente, por otro lado estaremos agregando que los disparos de nuestra nave puedan destruir los cohetes y estos tengan la animación de una explosión al destruirse y por último agregaremos un contador para saber cuántos misiles hemos destruido a lo largo del juego.
Permitiendo que nuestra nave dispare
Vamos a ir a nuestro archivo game.py y agregaremos un poco de código para que nuestra nave pueda disparar, en nuestra clase naveEspacial vamos a gregar 3 métodos nuevos y también crearemos la clase Proyectil:
class NaveEspacial(pygame.sprite.Sprite): # ... def disparar(self, x, y): disparo = Proyectil(x, y) self.listaDisparo.append(disparo) self.disparo.set_volume(0.02) # Le establecemos el volumen al sonido disparo self.disparo.play() # Reproducimos el sonido disparo # enfriamiento de disparo normal def enfriamiento_disparo(self): self.DISPARO_DELAY = 30 if self.contador_regresivo >= self.DISPARO_DELAY: self.contador_regresivo = 0 elif self.contador_regresivo > 0: self.contador_regresivo += 1 # enfriamiento de disparo con bonus activado def enfriamiento_disparo_bonus(self): self.DISPARO_DELAY = 15 # Disparamos más rápido if self.contador_regresivo >= self.DISPARO_DELAY: self.contador_regresivo = 0 elif self.contador_regresivo > 0: self.contador_regresivo += 1 # Creamos la clase Proyectil que es la que llamaremos al momento de que nuestra nave dispare class Proyectil(pygame.sprite.Sprite): DISPARO = os.path.join('assets', 'disparorojo1.png') # Cargamos la imagen de nuestro disparo def __init__(self, posx, posy): super().__init__() self.disparo_img = pygame.image.load(self.DISPARO) self.cuerpo = self.disparo_img.get_rect() self.velocidad_disparo = 5 self.cuerpo.top = posy self.cuerpo.left = posx def trayectoria(self): self.cuerpo.top = self.cuerpo.top - self.velocidad_disparo def dibujar(self, superficie): superficie.blit(self.disparo_img, self.cuerpo)
En este punto, nuestra nave cumple con los requisitos para poder disparar. Ya que tiene un método disparo que se encarga de llamar a la clase Proyectil y crear el disparo con las configuraciones pertinentes que tiene la clase Proyectil.
Pero si ejecutamos el juego en este punto, veremos que no podemos disparar. Eso es porque tenemos el código pero no lo estamos ejecutando dentro de nuestro juego, entonces para que nuestra nave pueda disparar tenemos que hacer lo siguiente.
Vamos a ir a nuestra función juego y donde se encuentra programado el movimiento de nuestra nave al pulsar las teclas y vamos a incluir ahora una nueva tecla, en mi caso usaré la tecla espacio, pero tú puedes usar cualquier otra tecla para disparar, luego de incluir la tecla le asignamos que la acción que queremos que produzca es para que nuestra nave dispare y el código que debemos agregar es el siguiente:
if teclas[pygame.K_SPACE]: x,y = jugador.cuerpo.center # el método .center me regresa el centro de la coordenada X y el centro de Y if jugador.contador_regresivo == 0: # Si el contador es igual a 0 nuestra nave va a disparar jugador.disparar(x -50, y - 50) # Nuestra nave llama al método disparar que a su vez realiza una instancia de la clase Proyectil jugador.contador_regresivo = 1 # igualamos a 1 para activar el contador y comience el enfriamiento del disparo
Ahora solo resta hacer una cosa para que nuestra nave pueda disparar, vamos a dirigirnos dentro de nuestra función juego nuevamente y debajo de la linea de código donde dibujamos nuestro jugador (la nave), para ser más especifico debajo de jugador.dibujar(VENTANA)
colocaremos el siguiente código:
texto_cohetes_destruidos = texto_enjuego.render('Cohetes destruidos:{}'.format(len(contador_misiles_destruidos)), 1, (151,151,151)) # Creamos el texto de cohetes destruidos VENTANA.blit(texto_cohetes_destruidos, (10,100)) # Pintamos el texto de cohetes destruidos dentro de nuestra ventana de juego # Si la lista de disparos no esta vacía, ejecutará el código donde recorremos la lista y dibujamos cada disparo que haga nuestra nave espacial if len(jugador.listaDisparo): if perdiste == False: for x in jugador.listaDisparo: x.dibujar(VENTANA) x.trayectoria() # Llamamos al método enfriamiento_disparo o enfriamiento_disparo_bonus para poder hacer disparos normales o más rápidos dependiendo si el bonus está activo o no esto se usará más adelante cuando agreguemos el bonus, ya que por ahora el único disparo permitido será el que se encuentra dentro del else if jugador.bonificacion == True: jugador.enfriamiento_disparo_bonus() else: jugador.enfriamiento_disparo()
A este punto si ejecutamos el código ya nuestra nave podrá disparar.
Permitiendo que nuestra nave destruya los cohetes cuando el disparo de la nave los impacte
Para lograr esto, solo debemos escribir un poco más de código ya que anteriormente teníamos cargado todos los archivos de sonido y las imágenes que usaremos, ahora solo resta llamar a los objetos y sus métodos que guardan dichos sonidos e imágenes.
Entonces nos dirigimos a nuestra función juego y donde recorremos la lista de disparos de nuestro jugador, agregaremos un poco más de código y ahora ese bloque de código debe lucir así:
if len(jugador.listaDisparo): if perdiste == False: for x in jugador.listaDisparo: x.dibujar(VENTANA) x.trayectoria() # Eliminamos el disparo que llegue a la parte superior de la pantalla if x.cuerpo.top < 20: jugador.listaDisparo.remove(x) # Para saber si colisiona un disparo con un misil, colocamos un else con el siguiente código else: for cohete in cantidad_misiles: if x.cuerpo.colliderect(cohete.cuerpo_misil): # Si el disparo golpea a un enemigo, le decimos que lo elimine destruido = pygame.mixer.Sound(MISIL_DESTRUIDO) destruido.set_volume(0.05) destruido.play() cantidad_misiles_destruidos.append(cohete) # Guardamos los misiles que se vayan destruyendo en la otra lista cantidad_misiles.remove(cohete) # Removemos los misiles destruidos de la lista try: # Validamos si existe el disparo, porque arroja errores algunas veces durante la ejecución del juego jugador.listaDisparo.remove(x) # Removemos el disparo del jugador except ValueError: print('Se destruyeron dos misiles con un disparo, ¡GENIAL!') puntos += 500 # Por cada 2 misiles que destruyamos le sumaremos 500 puntos al jugador puntos += 10 # Si no ocurre el error por cada misil que destruyamos le sumaremos 10 puntos y de esta manera nos aprovechamos de ese error # Recorremos los misiles destruidos y le cambiamos su imagen para dar el efecto de que el misil se destruye for cohete in cantidad_misiles_destruidos: cohete.misil_img = cohete.misil_dest cohete.dibujar(VENTANA) if cohete.cuerpo_misil_dest.top == 0: contador_misiles_destruidos.append(cohete) cantidad_misiles_destruidos.remove(cohete)
A partir de este punto, nuestros disparos podrán destruir los cohetes y si los cohetes llegan al final de la pantalla sin ser destruidos, se le restaran 50 puntos al jugador, por cada cohete destruido se sumaran 10 puntos y el contador de cohetes lo contará para llevar un registro de cuantos cohetes hemos destruido a lo largo de la partida.
Permitiendo que los cohetes hagan perder al jugador si ambos colisionan
Para esto solo debemos dirigirnos a el bloque de código donde recorremos cada misil y hacer que luzca de esta manera:
for misil in cantidad_misiles: misil.dibujar(VENTANA) if perdiste == False: misil.trayectoria() if misil.cuerpo_misil.top > ALTO: cantidad_misiles.remove(misil) puntos -= 50 # Por cada misil que toque el final de la pantalla restaremos 50 puntos # Cuando un misil toque el cuerpo del jugador perderemos if misil.cuerpo_misil.colliderect(jugador.cuerpo): pygame.mixer.music.stop() # detenemos la musica porque ha terminado el juego juego_terminado.set_volume(0.05) # Establecemos el volumen del sonido juego terminado juego_terminado.play() # Reproducimos el sonido juego terminado perdiste = True # Cambiamos la variable para avisarle a nuestro juego que el jugador perdió
A este punto, ya los cohetes hacen perder a nuestro jugador. También veras que si jugamos y logramos una puntuación y si perdemos se reproduce el sonido de juego terminado y además nos llevara a la pantalla de inicio, al pulsar nuevamente cualquier tecla como lo indica la pantalla, comenzaremos a jugar nuevamente y la variable record habrá almacenado la puntuación del juego anterior.
Agregando el Bonus para disparar 3 veces más rápido por 20 segundos
Para finalizar estaremos agregando el bonus, para esto necesitaremos crear una nueva clase a la que llamaremos Bonus. Para seguir con el orden la crearemos debajo de la ultima clase que creamos que fue la clase Misil:
class Bonus(pygame.sprite.Sprite): BONUS = os.path.join('assets', 'bonus1.png') def __init__(self, posx, posy): super().__init__() self.bonus_img = pygame.image.load(self.BONUS) self.cuerpo_bonus = self.bonus_img.get_rect() self.cuerpo_bonus.left = posx self.cuerpo_bonus.top = posy self.velocidad_bonus = 5 def trayectoria(self): self.cuerpo_bonus.top = self.cuerpo_bonus.top + self.velocidad_bonus def dibujar(self, superficie): superficie.blit(self.bonus_img, (self.cuerpo_bonus.left, self.cuerpo_bonus.top))
Una vez hecho esto, ya tenemos nuestra clase Bonus lista para que pueda unirse a nuestro juego. Ahora lo que debemos hacer es dirigirnos nuevamente a nuestra funcion juego y agregar el siguiente bloque de código:
# Creamos una sentencia que siempre sea True, así como lo hicimos anteriormente if True: contador_bonus += 1 # Luego cremos la instancia del bonus cuando el contador llegue a 1800 que son aproximadamente casí 2 minutos if contador_bonus == caida_bonus: caida_bonus += 200 # Aumenta el tiempo de caida del bonus en 200 para el próximo bonus posx = random.randint(0, 580) bonus = Bonus(posx, -100) cantidad_bonus.append(bonus) contador_bonus = 0 # Dibujamos el bonus if len(cantidad_bonus): if perdiste == False: for bonus in cantidad_bonus: bonus.trayectoria() bonus.dibujar(VENTANA) if bonus.cuerpo_bonus.top > ALTO: cantidad_bonus.remove(bonus) else: if bonus.cuerpo_bonus.colliderect(jugador.cuerpo): jugador.bonificacion = True cantidad_bonus.remove(bonus) # Lógica para determinar si el bonus se encuentra activado if jugador.bonificacion: duracion_bonus += 1 if duracion_bonus > 500: duracion_bonus = 0 jugador.bonificacion = False
Listo, ahora si ejecutamos el juego tendremos nuestro bonus y al cogerlo nuestra nave podrá disparar 3 veces más rápido por 20 segundos.
Con esto finalizamos el juego que nos ha ayudado bastante a aprender sobre la librería pygame, también es importante que sepas que este código puede seguir escalando, por ejemplo podemos agregar:
- Nuevos bonus
- Un sistema de niveles
- Diferentes tipos de disparos
- Nuevos adversarios que disparen
➡ Continúa aprendiendo sobre desarrollo de videojuegos con python en nuestro Curso Python de Videojuegos: