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: