subida a repo propio
3
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
10
.idea/juego_tanque.iml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
4
.idea/misc.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (juego_tanque)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/juego_tanque.iml" filepath="$PROJECT_DIR$/.idea/juego_tanque.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
33
README.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# tanques
|
||||||
|
Juego de tanques 2D desarrollado en Python con pygame
|
||||||
|
<p align="center"> <img src="capturas_juego/captura_inicio.png" width="400" height="300"> </p>
|
||||||
|
<p align="center"> <img src="capturas_juego/captura_fin.png" width="400" height="300"> </p>
|
||||||
|
|
||||||
|
Requisitos: Tener instalado python y pip
|
||||||
|
|
||||||
|
Como usarlo:
|
||||||
|
|
||||||
|
1.- Descargar codigo del repositorio:
|
||||||
|
|
||||||
|
$ cd
|
||||||
|
|
||||||
|
$ git clone https://gitea.soloconlinux.org.es/luisgulo/tanques.git
|
||||||
|
|
||||||
|
$ cd tanques
|
||||||
|
|
||||||
|
|
||||||
|
2.- Instalar modulo pygame
|
||||||
|
|
||||||
|
$ source venv/bin/activate
|
||||||
|
|
||||||
|
$ pip install pygame
|
||||||
|
|
||||||
|
|
||||||
|
3a.- Lanzar juego (modo directo):
|
||||||
|
|
||||||
|
$ chmod +x guerra_tanques.py
|
||||||
|
|
||||||
|
$ ./guerra_tanques.py
|
||||||
|
|
||||||
|
3b.- Lanzar juego (mediante python)
|
||||||
|
$ python ./guerra_tanques.py
|
BIN
__pycache__/clase_bala.cpython-39.pyc
Normal file
BIN
__pycache__/clase_boton.cpython-39.pyc
Normal file
BIN
__pycache__/clase_enemigo.cpython-39.pyc
Normal file
BIN
__pycache__/clase_fondo.cpython-39.pyc
Normal file
BIN
__pycache__/clase_puntuaciones.cpython-39.pyc
Normal file
BIN
__pycache__/clase_tanque.cpython-39.pyc
Normal file
BIN
__pycache__/clase_vidas.cpython-39.pyc
Normal file
BIN
__pycache__/settings.cpython-39.pyc
Normal file
BIN
capturas_juego/captura_fin.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
capturas_juego/captura_inicio.png
Normal file
After Width: | Height: | Size: 31 KiB |
47
clase_bala.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import pygame
|
||||||
|
from pygame.sprite import Sprite
|
||||||
|
#from clase_tanque import Tanque
|
||||||
|
|
||||||
|
class Bala(Sprite):
|
||||||
|
''' Clase para gestionar las balas disparadas '''
|
||||||
|
def __init__(self, juego, direccion):
|
||||||
|
''' Crear objeto desde posicion del tanque '''
|
||||||
|
super().__init__()
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.settings = juego.settings
|
||||||
|
self.color = self.settings.bala_color
|
||||||
|
# Crear rectangulo para la bala en posicion (0,0) y luego la colocamos
|
||||||
|
self.rect = pygame.Rect(0,0, self.settings.bala_ancho, self.settings.bala_largo)
|
||||||
|
self.rect.midtop = juego.tanque.rect.midtop
|
||||||
|
self.direccion_bala = direccion
|
||||||
|
# defecto
|
||||||
|
self.x = float(self.rect.x)
|
||||||
|
self.y = float(self.rect.y)
|
||||||
|
if self.direccion_bala == 'Arr':
|
||||||
|
self.x = float(self.rect.x)
|
||||||
|
self.y = float(self.rect.y)
|
||||||
|
if self.direccion_bala == 'Aba':
|
||||||
|
self.x = float(self.rect.x)
|
||||||
|
self.y = float(self.rect.y) + 64
|
||||||
|
if self.direccion_bala == 'Dcha':
|
||||||
|
self.x = float(self.rect.x) + 31
|
||||||
|
self.y = float(self.rect.y) + 30
|
||||||
|
if self.direccion_bala == 'Izda':
|
||||||
|
self.x = float(self.rect.x) - 31
|
||||||
|
self.y = float(self.rect.y) + 30
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.direccion_bala == 'Arr':
|
||||||
|
self.y -= self.settings.bala_velocidad
|
||||||
|
if self.direccion_bala == 'Aba':
|
||||||
|
self.y += self.settings.bala_velocidad
|
||||||
|
if self.direccion_bala == 'Dcha':
|
||||||
|
self.x += self.settings.bala_velocidad
|
||||||
|
if self.direccion_bala == 'Izda':
|
||||||
|
self.x -= self.settings.bala_velocidad
|
||||||
|
|
||||||
|
self.rect.x = self.x
|
||||||
|
self.rect.y = self.y
|
||||||
|
|
||||||
|
def pintar_bala(self):
|
||||||
|
pygame.draw.rect(self.screen, self.color, self.rect)
|
28
clase_boton.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import pygame.font
|
||||||
|
|
||||||
|
class Boton:
|
||||||
|
def __init__(self, juego, mensaje):
|
||||||
|
''' Inicializar atributos del boton '''
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.screen_rect = self.screen.get_rect()
|
||||||
|
# Ajustar dimensiones y propiedades del boton
|
||||||
|
self.width, self.height = 200, 50
|
||||||
|
self.button_color = (0, 155, 0)
|
||||||
|
self.text_color = (255, 255, 255)
|
||||||
|
self.font = pygame.font.SysFont(None, 48)
|
||||||
|
# Crear objeto rectangular del boton y centrarlo
|
||||||
|
self.rect = pygame.Rect(0, 0, self.width, self.height)
|
||||||
|
self.rect.center = self.screen_rect.center
|
||||||
|
# Preparamos el mensaje del boton (1 sola vez)
|
||||||
|
self._preparar_mensaje(mensaje)
|
||||||
|
|
||||||
|
def _preparar_mensaje(self, mensaje):
|
||||||
|
''' Convertir el mensaje en imagen '''
|
||||||
|
self.msg_image = self.font.render(mensaje, True, self.text_color, self.button_color)
|
||||||
|
self.msg_image_rect = self.msg_image.get_rect()
|
||||||
|
self.msg_image_rect.center = self.rect.center
|
||||||
|
|
||||||
|
def dibujar_boton(self):
|
||||||
|
''' Dibujamos boton vacio y luego el texto '''
|
||||||
|
self.screen.fill(self.button_color, self.rect)
|
||||||
|
self.screen.blit(self.msg_image, self.msg_image_rect)
|
97
clase_enemigo.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
from pygame.sprite import Sprite
|
||||||
|
|
||||||
|
class Enemigo(Sprite):
|
||||||
|
''' Clase para representar un enemigo '''
|
||||||
|
|
||||||
|
def __init__(self, juego):
|
||||||
|
''' Inicializa al enemigo y lo coloca '''
|
||||||
|
super().__init__()
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.direccion = 'Aba'
|
||||||
|
# Cargamos imagen del enemigo
|
||||||
|
direccion = random.randrange(1,5)
|
||||||
|
if direccion == 1:
|
||||||
|
self.direccion = 'Aba'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_abajo_01.png'
|
||||||
|
if direccion == 2:
|
||||||
|
self.direccion = 'Arr'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_arriba_01.png'
|
||||||
|
if direccion == 3:
|
||||||
|
self.direccion = 'Dcha'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_derecha_01.png'
|
||||||
|
if direccion == 4:
|
||||||
|
self.direccion = 'Izda'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_izquierda_01.png'
|
||||||
|
self.velocidad = 1
|
||||||
|
self.avance = random.randrange(25,200)
|
||||||
|
self.vEnemigo = True
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
# Colocar al enemigo en su posicion
|
||||||
|
self.rect.x = self.rect.width
|
||||||
|
self.rect.y = self.rect.height
|
||||||
|
# guardamos posicion exacta del enemigo
|
||||||
|
self.x = float(self.rect.x)
|
||||||
|
self.y = float(self.rect.y)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
''' Mover a los enemigos '''
|
||||||
|
if self.vEnemigo:
|
||||||
|
if self.direccion == 'Aba':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_abajo_01.png'
|
||||||
|
if self.direccion == 'Arr':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_arriba_01.png'
|
||||||
|
if self.direccion == 'Dcha':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_derecha_01.png'
|
||||||
|
if self.direccion == 'Izda':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_izquierda_01.png'
|
||||||
|
else:
|
||||||
|
if self.direccion == 'Aba':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_abajo_02.png'
|
||||||
|
if self.direccion == 'Arr':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_arriba_02.png'
|
||||||
|
if self.direccion == 'Dcha':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_derecha_02.png'
|
||||||
|
if self.direccion == 'Izda':
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_izquierda_02.png'
|
||||||
|
self.vEnemigo = not self.vEnemigo
|
||||||
|
# Desplazar tanque enemigo
|
||||||
|
if self.avance <= 0:
|
||||||
|
self.avance = random.randrange(25,200)
|
||||||
|
direccion = random.randrange(1, 5)
|
||||||
|
if direccion == 1:
|
||||||
|
self.direccion = 'Aba'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_abajo_01.png'
|
||||||
|
if direccion == 2:
|
||||||
|
self.direccion = 'Arr'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_arriba_01.png'
|
||||||
|
if direccion == 3:
|
||||||
|
self.direccion = 'Dcha'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_derecha_01.png'
|
||||||
|
if direccion == 4:
|
||||||
|
self.direccion = 'Izda'
|
||||||
|
self.rutaImagen = 'imagenes/enemigo_izquierda_01.png'
|
||||||
|
else:
|
||||||
|
if self.direccion == 'Arr':
|
||||||
|
self.rect.y -= self.velocidad
|
||||||
|
if self.direccion == 'Aba':
|
||||||
|
self.rect.y += self.velocidad
|
||||||
|
if self.direccion == 'Dcha':
|
||||||
|
self.rect.x += self.velocidad
|
||||||
|
if self.direccion == 'Izda':
|
||||||
|
self.rect.x -= self.velocidad
|
||||||
|
# Restamos movimiento realizado
|
||||||
|
self.avance -= self.velocidad
|
||||||
|
# Cambiar direccion si se sale de pantalla
|
||||||
|
pantalla = self.screen.get_rect()
|
||||||
|
if self.rect.x <= pantalla.left: # choca lado izdo
|
||||||
|
self.direccion = 'Dcha'
|
||||||
|
if self.rect.x >= pantalla.right - 64:
|
||||||
|
self.direccion = 'Izda'
|
||||||
|
if self.rect.y <= pantalla.top:
|
||||||
|
self.direccion = 'Aba'
|
||||||
|
if self.rect.y >= pantalla.bottom - 64:
|
||||||
|
self.direccion = 'Arr'
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
11
clase_fondo.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Fondo:
|
||||||
|
def __init__(self, juego):
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.rutaImagen = 'imagenes/fondo.png'
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
||||||
|
|
||||||
|
def blitme(self):
|
||||||
|
''' Pintar fondo actual '''
|
||||||
|
self.screen.blit(self.image, (0, 0))
|
43
clase_puntuaciones.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import pygame.font
|
||||||
|
|
||||||
|
class Puntuacion:
|
||||||
|
''' Clase par mostrar informacion de la puntuacion '''
|
||||||
|
|
||||||
|
def __init__(self, juego):
|
||||||
|
''' Inicializar puntuacion '''
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.screen_rect = self.screen.get_rect()
|
||||||
|
self.settings = juego.settings
|
||||||
|
self.puntos = 0
|
||||||
|
self.nivel = 1
|
||||||
|
''' Ajuste de la fuente de la puntuacion '''
|
||||||
|
self.text_color = (30, 30, 30)
|
||||||
|
self.font = pygame.font.SysFont(None,48)
|
||||||
|
self.preparar_puntuacion()
|
||||||
|
self.preparar_nivel()
|
||||||
|
|
||||||
|
def preparar_puntuacion(self):
|
||||||
|
''' Convertir puntuacion en imagen renderizada '''
|
||||||
|
score_str = "Ptos: " + str(self.puntos)
|
||||||
|
self.score_image = self.font.render(score_str, True, self.text_color)
|
||||||
|
''' Puntuacion en parte superior derecha '''
|
||||||
|
self.score_rect = self.score_image.get_rect()
|
||||||
|
self.score_rect.right = self.screen_rect.right - 20
|
||||||
|
self.score_rect.top = 40
|
||||||
|
|
||||||
|
def preparar_nivel(self):
|
||||||
|
''' convertir texto en imagen '''
|
||||||
|
nivel_str = f"Nivel: {self.nivel}"
|
||||||
|
self.nivel_image = self.font.render(nivel_str, True, self.text_color)
|
||||||
|
''' Nivel en parte sup. derecha y debajo de los puntos '''
|
||||||
|
self.nivel_rect = self.nivel_image.get_rect()
|
||||||
|
self.nivel_rect.right = self.screen_rect.right - 20
|
||||||
|
self.nivel_rect.top = 10
|
||||||
|
|
||||||
|
def mostrar_puntacion(self):
|
||||||
|
''' dibujar la puntacion '''
|
||||||
|
self.preparar_puntuacion()
|
||||||
|
self.screen.blit(self.score_image, self.score_rect)
|
||||||
|
''' dibujar el nivel '''
|
||||||
|
self.preparar_nivel()
|
||||||
|
self.screen.blit(self.nivel_image, self.nivel_rect)
|
59
clase_tanque.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import pygame
|
||||||
|
from settings import Settings
|
||||||
|
|
||||||
|
class Tanque:
|
||||||
|
''' Esta clase gestiona el tanque '''
|
||||||
|
def __init__(self, juego):
|
||||||
|
self.settings = Settings()
|
||||||
|
''' Iniciar tanque y fija su posicion '''
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.screen_rect = juego.screen.get_rect()
|
||||||
|
''' Leer imagen y cargar su rectangulo '''
|
||||||
|
self.vTanque = True
|
||||||
|
self.rutaImagen = 'imagenes/tanque_arriba_01.png'
|
||||||
|
''' Permitir movimiento continuo con teclas '''
|
||||||
|
self.mover_derecha = False
|
||||||
|
self.mover_izquierda = False
|
||||||
|
self.mover_arriba = False
|
||||||
|
self.mover_abajo = False
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
''' Posicion inicial (abajo en el centro) '''
|
||||||
|
self.rect.midbottom = self.screen_rect.midbottom
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.mover_derecha:
|
||||||
|
ruta = 'imagenes/tanque_derecha_'
|
||||||
|
self.rect.x += self.settings.velocidad_tanque
|
||||||
|
if self.rect.x >= 800 - 64:
|
||||||
|
self.rect.x = 800 - 64
|
||||||
|
elif self.mover_izquierda:
|
||||||
|
ruta = 'imagenes/tanque_izquierda_'
|
||||||
|
self.rect.x -= self.settings.velocidad_tanque
|
||||||
|
if self.rect.x <= 0:
|
||||||
|
self.rect.x = 0
|
||||||
|
elif self.mover_arriba:
|
||||||
|
ruta = 'imagenes/tanque_arriba_'
|
||||||
|
self.rect.y -= self.settings.velocidad_tanque
|
||||||
|
if self.rect.y <= 0:
|
||||||
|
self.rect.y = 0
|
||||||
|
elif self.mover_abajo:
|
||||||
|
ruta = 'imagenes/tanque_abajo_'
|
||||||
|
self.rect.y += self.settings.velocidad_tanque
|
||||||
|
if self.rect.y >= 600 - 64:
|
||||||
|
self.rect.y = 600 - 64
|
||||||
|
else:
|
||||||
|
trocear = self.rutaImagen.split('_')
|
||||||
|
ruta = trocear[0] + '_' + trocear[1] + '_'
|
||||||
|
''' Simular moviento ruedas tanque '''
|
||||||
|
if self.vTanque == True:
|
||||||
|
ruta = ruta + '01.png'
|
||||||
|
else:
|
||||||
|
ruta = ruta + '02.png'
|
||||||
|
self.rutaImagen = ruta
|
||||||
|
self.image = pygame.image.load(ruta)
|
||||||
|
self.vTanque = not self.vTanque
|
||||||
|
|
||||||
|
def blitme(self):
|
||||||
|
''' Pintar tanque en posicion actual '''
|
||||||
|
self.screen.blit(self.image, self.rect)
|
21
clase_vidas.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import pygame
|
||||||
|
from pygame.sprite import Sprite
|
||||||
|
|
||||||
|
class Vida(Sprite):
|
||||||
|
''' Clase para gestionar las vidas restantes '''
|
||||||
|
def __init__(self, juego):
|
||||||
|
super().__init__()
|
||||||
|
self.vidas_quedan = juego.vidas
|
||||||
|
self.screen = juego.screen
|
||||||
|
self.rutaImagen = 'imagenes/tanque_vida.png'
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
# Colocar la vida en su posicion
|
||||||
|
self.rect.x = self.rect.width
|
||||||
|
self.rect.y = self.rect.height
|
||||||
|
# guardamos posicion exacta de la vida
|
||||||
|
self.x = float(self.rect.x)
|
||||||
|
self.y = float(self.rect.y)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.image = pygame.image.load(self.rutaImagen)
|
244
guerra_tanques.py
Executable file
|
@ -0,0 +1,244 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
from settings import Settings
|
||||||
|
from clase_tanque import Tanque
|
||||||
|
from clase_fondo import Fondo
|
||||||
|
from clase_bala import Bala
|
||||||
|
from clase_enemigo import Enemigo
|
||||||
|
from clase_puntuaciones import Puntuacion
|
||||||
|
from clase_vidas import Vida
|
||||||
|
from clase_boton import Boton
|
||||||
|
|
||||||
|
class GuerraTanque:
|
||||||
|
''' Clase general para gestionar recursos y juego '''
|
||||||
|
def __init__(self):
|
||||||
|
''' Inicializar el juego y crear recursos '''
|
||||||
|
pygame.init()
|
||||||
|
# Leemos valores de configuracion del juego
|
||||||
|
self.settings = Settings()
|
||||||
|
# Leemos numero de vidas
|
||||||
|
self.vidas = self.settings.vidas
|
||||||
|
self.juego_activo = False
|
||||||
|
# Puntuacion a Cero
|
||||||
|
self.puntuacion = 0
|
||||||
|
# Preparamos pantalla
|
||||||
|
self.screen = pygame.display.set_mode((self.settings.pantalla_ancho , self.settings.pantalla_alto))
|
||||||
|
pygame.display.set_caption("GUERRA DE TANQUES - 'ESC' para salir")
|
||||||
|
pygame.display.set_icon(pygame.image.load('imagenes/tanque_derecha_01.png'))
|
||||||
|
# Incluir Fondo
|
||||||
|
self.fondo_juego = Fondo(self)
|
||||||
|
# Incluimos la puntuacion
|
||||||
|
self.puntuacion = Puntuacion(self)
|
||||||
|
# Incluimos las vidas
|
||||||
|
self.tanques_que_nos_quedan = pygame.sprite.Group()
|
||||||
|
self._crear_vidas()
|
||||||
|
# Iniciar tanque
|
||||||
|
self.tanque = Tanque(self)
|
||||||
|
self.balas = pygame.sprite.Group()
|
||||||
|
self.mirando_hacia='Arr'
|
||||||
|
# Iniciar enemigos
|
||||||
|
self.enemigos = pygame.sprite.Group()
|
||||||
|
self._crear_escuadron()
|
||||||
|
self.ruido_cadenas = pygame.mixer.Sound('sonidos/ruido_cadenas_tanque.wav')
|
||||||
|
self.boton_iniciar = Boton(self, "Iniciar")
|
||||||
|
|
||||||
|
def run_game(self):
|
||||||
|
#pygame.mixer.Sound('sonidos/retro-sound.mp3').play()
|
||||||
|
#time.sleep(0.5)
|
||||||
|
#pygame.mixer.stop()
|
||||||
|
''' Bucle infinito del juego '''
|
||||||
|
while True:
|
||||||
|
self.fondo_juego
|
||||||
|
''' Leemos eventos de teclado y raton '''
|
||||||
|
self.chequear_eventos()
|
||||||
|
if self.juego_activo: # Solo si esta el juego activo
|
||||||
|
''' Actualizar tanque '''
|
||||||
|
self.tanque.update()
|
||||||
|
''' Gestionamos los disparos y las balas '''
|
||||||
|
self._actualizar_bala()
|
||||||
|
''' Gestionamos los enemigos '''
|
||||||
|
self.enemigos.update()
|
||||||
|
# Si chocamos con enemigo morimos
|
||||||
|
if pygame.sprite.spritecollideany(self.tanque,self.enemigos):
|
||||||
|
self._chequear_vidas()
|
||||||
|
''' Actualizar pantalla '''
|
||||||
|
self.actualizar_pantalla()
|
||||||
|
|
||||||
|
def _chequear_vidas(self):
|
||||||
|
# Chocamos con un tanque... Quitamos una vida
|
||||||
|
self.vidas -= 1
|
||||||
|
self.puntuacion.nivel -= 1
|
||||||
|
self.tanques_que_nos_quedan.remove()
|
||||||
|
# Situamos tanque en posicion inicial
|
||||||
|
self.tanque.rect.midbottom = self.screen.get_rect().midbottom
|
||||||
|
# Vaciamos de enemigos
|
||||||
|
self.enemigos.empty()
|
||||||
|
self.tanques_que_nos_quedan.empty()
|
||||||
|
# Cheequeamos si hay que pintar el game over
|
||||||
|
if self.vidas > 0:
|
||||||
|
pygame.mixer.Sound('sonidos/explosion_tanque.wav').play()
|
||||||
|
# Hacemos una pequeña pausa
|
||||||
|
time.sleep(0.5)
|
||||||
|
else:
|
||||||
|
self.puntuacion.nivel += 1
|
||||||
|
# Mensaje de GAME OVER
|
||||||
|
print("G A M E O V E R")
|
||||||
|
pygame.mixer.Sound('sonidos/game_over.wav').play()
|
||||||
|
self.juego_activo = False
|
||||||
|
pygame.mouse.set_visible(True)
|
||||||
|
|
||||||
|
def actualizar_pantalla(self):
|
||||||
|
''' Redibujar la pantalla '''
|
||||||
|
# Recargar imagenes y cambiar nueva pantalla
|
||||||
|
# Relleno de color del fondo
|
||||||
|
self.screen.fill(self.settings.color_fondo)
|
||||||
|
# Incluir recursos del juego
|
||||||
|
self.fondo_juego.blitme()
|
||||||
|
self.tanque.blitme()
|
||||||
|
if self.vidas == 0:
|
||||||
|
img_fin_juego = pygame.image.load('imagenes/game_over.png')
|
||||||
|
self.screen.blit(img_fin_juego, (120, 300))
|
||||||
|
pygame.display.set_caption("GUERRA DE TANQUES - 'ESC' para salir")
|
||||||
|
''' Balas/Disparos'''
|
||||||
|
for disparo in self.balas.sprites():
|
||||||
|
disparo.pintar_bala()
|
||||||
|
''' Escuadron enemigo '''
|
||||||
|
self.enemigos.draw(self.screen)
|
||||||
|
''' Vamos grabando la puntuacion del juego '''
|
||||||
|
self.puntuacion.mostrar_puntacion()
|
||||||
|
# Pintamos grupo de mini-tanques que indican la vida
|
||||||
|
self.tanques_que_nos_quedan.draw(self.screen)
|
||||||
|
# Dibujar boton de iniciar partida si juego inactivo
|
||||||
|
if not self.juego_activo:
|
||||||
|
self.boton_iniciar.dibujar_boton()
|
||||||
|
# Pintamos la ultima pantalla que hemos dibujado en memoria
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
def _crear_escuadron(self):
|
||||||
|
''' Crear un escuadron de 5 tanques enemigos '''
|
||||||
|
enemigo = Enemigo(self)
|
||||||
|
random.seed()
|
||||||
|
num_enemigos = 5
|
||||||
|
|
||||||
|
for i in range(num_enemigos):
|
||||||
|
enemigo = Enemigo(self)
|
||||||
|
enemigo.velocidad = (self.puntuacion.nivel / 4) + 0.5
|
||||||
|
iniX = int((800/num_enemigos) * int(i))
|
||||||
|
finX= int(iniX + (800/num_enemigos))
|
||||||
|
#print(f"iniX {iniX}")
|
||||||
|
#print(f"finX {finX}")
|
||||||
|
enemigo.x = random.randrange(iniX, finX)
|
||||||
|
y = 300
|
||||||
|
enemigo.y = random.randrange(0, y)
|
||||||
|
enemigo.rect.x = enemigo.x
|
||||||
|
enemigo.rect.y = enemigo.y
|
||||||
|
self.enemigos.add(enemigo)
|
||||||
|
|
||||||
|
def _crear_vidas(self):
|
||||||
|
''' Crear tantos mini-tanques de vidas como vidas queden '''
|
||||||
|
mini_tanque = Vida(self)
|
||||||
|
vidas_quedan = self.vidas
|
||||||
|
for i in range(vidas_quedan):
|
||||||
|
mini_tanque = Vida(self)
|
||||||
|
mini_tanque.x = (28 * i) + 5
|
||||||
|
mini_tanque.y = 0
|
||||||
|
mini_tanque.rect.x = mini_tanque.x
|
||||||
|
mini_tanque.rect.y = mini_tanque.y
|
||||||
|
self.tanques_que_nos_quedan.add(mini_tanque)
|
||||||
|
|
||||||
|
def _disparar_bala(self):
|
||||||
|
''' Crear una bala nueva e incluirla en Group '''
|
||||||
|
if len(self.balas) < self.settings.balas_permitidas:
|
||||||
|
nueva_bala = Bala(self, self.mirando_hacia)
|
||||||
|
self.balas.add(nueva_bala)
|
||||||
|
pygame.mixer.Sound('sonidos/sonido_bala.wav').play()
|
||||||
|
|
||||||
|
def _actualizar_bala(self):
|
||||||
|
''' Crear nuevas balas y eliminar las viejas '''
|
||||||
|
# Posicion y movimiento de las balas
|
||||||
|
self.balas.update()
|
||||||
|
# Eliminamos balas que se salen de la pantalla
|
||||||
|
pantalla = self.screen.get_rect()
|
||||||
|
for disparo in self.balas.copy():
|
||||||
|
if disparo.rect.bottom <= 0 or disparo.rect.top >= 600 or disparo.rect.left <= 0 or disparo.rect.left >= 800:
|
||||||
|
self.balas.remove(disparo)
|
||||||
|
# Chequear si destruyo enemigo
|
||||||
|
# Bala choca con Enemigo => Se destruye Bala (True), Se destruye Enemigo (True)
|
||||||
|
colision = pygame.sprite.groupcollide(self.balas, self.enemigos, True, True)
|
||||||
|
# Si hay datos en colision es que alcanzamos al enemigo
|
||||||
|
if len(colision) > 0:
|
||||||
|
# 5 puntos por tanque
|
||||||
|
self.puntuacion.puntos += 5
|
||||||
|
|
||||||
|
pygame.mixer.Sound('sonidos/explosion_enemigo.wav').play()
|
||||||
|
# Si no hay enemigos creo un nuevo escuadron
|
||||||
|
if not self.enemigos:
|
||||||
|
# 7 puntos por acabar con escuadra completa
|
||||||
|
self.puntuacion.puntos += 7
|
||||||
|
self.puntuacion.nivel += 1
|
||||||
|
# Eliminar Balas
|
||||||
|
self.balas.empty()
|
||||||
|
# Crear escuadron
|
||||||
|
self._crear_escuadron()
|
||||||
|
# Vidas
|
||||||
|
self._crear_vidas()
|
||||||
|
|
||||||
|
def _chequear_boton_iniciar(self, posicion_raton):
|
||||||
|
''' Si pulsa raton iniciamos juego '''
|
||||||
|
if self.boton_iniciar.rect.collidepoint(posicion_raton):
|
||||||
|
self.juego_activo = True
|
||||||
|
pygame.mouse.set_visible(False)
|
||||||
|
|
||||||
|
def chequear_eventos(self):
|
||||||
|
''' Leemos eventos de teclado y raton '''
|
||||||
|
for evento in pygame.event.get():
|
||||||
|
if evento.type == pygame.QUIT:
|
||||||
|
sys.exit()
|
||||||
|
elif evento.type == pygame.KEYDOWN: # Detectar que se presiona tecla
|
||||||
|
self.ruido_cadenas.play(-1)
|
||||||
|
# Teclas: S, Q o ESC finalizan el juego
|
||||||
|
if evento.key == pygame.K_s or evento.key == pygame.K_q or evento.key == pygame.K_ESCAPE:
|
||||||
|
pygame.QUIT
|
||||||
|
sys.exit()
|
||||||
|
#if evento.key == pygame.K_i: # Iniciar
|
||||||
|
# self.juego_activo = True
|
||||||
|
if evento.key == pygame.K_RIGHT:
|
||||||
|
# mover tanque a la derecha
|
||||||
|
self.tanque.mover_derecha = True
|
||||||
|
self.mirando_hacia = 'Dcha'
|
||||||
|
if evento.key == pygame.K_LEFT:
|
||||||
|
# mover tanque a la izquierda
|
||||||
|
self.tanque.mover_izquierda = True
|
||||||
|
self.mirando_hacia = 'Izda'
|
||||||
|
if evento.key == pygame.K_UP:
|
||||||
|
# mover tanque hacia arriba
|
||||||
|
self.tanque.mover_arriba = True
|
||||||
|
self.mirando_hacia = 'Arr'
|
||||||
|
if evento.key == pygame.K_DOWN:
|
||||||
|
# mover tanque hacia abajo
|
||||||
|
self.tanque.mover_abajo = True
|
||||||
|
self.mirando_hacia = 'Aba'
|
||||||
|
if evento.key == pygame.K_SPACE:
|
||||||
|
self._disparar_bala()
|
||||||
|
elif evento.type == pygame.KEYUP: # Detener movimientos
|
||||||
|
self.ruido_cadenas.stop()
|
||||||
|
self.tanque.mover_izquierda = False
|
||||||
|
self.tanque.mover_derecha = False
|
||||||
|
self.tanque.mover_arriba = False
|
||||||
|
self.tanque.mover_abajo = False
|
||||||
|
elif evento.type == pygame.MOUSEBUTTONDOWN: # Si aprieta raton (en cualquier sitio)
|
||||||
|
posicion_raton = pygame.mouse.get_pos()
|
||||||
|
self._chequear_boton_iniciar(posicion_raton)
|
||||||
|
self.puntuacion.nivel = 1
|
||||||
|
self.puntuacion.puntos = 0
|
||||||
|
self.vidas = 3
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
''' Creamos instancia del juego y lo iniciamos '''
|
||||||
|
juego = GuerraTanque()
|
||||||
|
juego.run_game()
|
||||||
|
|
BIN
imagenes/enemigo_abajo_01.png
Normal file
After Width: | Height: | Size: 482 B |
BIN
imagenes/enemigo_abajo_02.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
imagenes/enemigo_arriba_01.png
Normal file
After Width: | Height: | Size: 479 B |
BIN
imagenes/enemigo_arriba_02.png
Normal file
After Width: | Height: | Size: 486 B |
BIN
imagenes/enemigo_derecha_01.png
Normal file
After Width: | Height: | Size: 458 B |
BIN
imagenes/enemigo_derecha_02.png
Normal file
After Width: | Height: | Size: 476 B |
BIN
imagenes/enemigo_izquierda_01.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
imagenes/enemigo_izquierda_02.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
imagenes/fondo.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
imagenes/game_over.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
imagenes/tanque_abajo_01.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
imagenes/tanque_abajo_02.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
imagenes/tanque_arriba_01.png
Normal file
After Width: | Height: | Size: 486 B |
BIN
imagenes/tanque_arriba_02.png
Normal file
After Width: | Height: | Size: 487 B |
BIN
imagenes/tanque_derecha_01.png
Normal file
After Width: | Height: | Size: 490 B |
BIN
imagenes/tanque_derecha_02.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
imagenes/tanque_izquierda_01.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
imagenes/tanque_izquierda_02.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
imagenes/tanque_vida.png
Normal file
After Width: | Height: | Size: 387 B |
1
requeriments.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pygame==2.4.0
|
1
runtime.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Python 3.9.2
|
18
settings.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class Settings:
|
||||||
|
''' Esta clase es para guardar toda la configuracion del juego '''
|
||||||
|
def __init__(self):
|
||||||
|
''' Inicializar los valores del juego '''
|
||||||
|
# Resolucion
|
||||||
|
self.pantalla_ancho = 800
|
||||||
|
self.pantalla_alto = 600
|
||||||
|
# Color fondo
|
||||||
|
self.color_fondo = (0, 50, 0)
|
||||||
|
self.velocidad_tanque = 1
|
||||||
|
''' Configuracion de las balas '''
|
||||||
|
self.bala_velocidad = 2
|
||||||
|
self.bala_ancho = 8
|
||||||
|
self.bala_largo = 8
|
||||||
|
self.bala_color = (60, 60, 60)
|
||||||
|
self.balas_permitidas = 3 # Num de disparos permitidos
|
||||||
|
self.vidas = 3
|
||||||
|
self.puntos = 0
|