#!/usr/bin/env python # -*- coding: utf-8 -*- #==================================================== # redoct.py - Juego de submarinos con Python/Pygame #---------------------------------------------------- # FJA - neocipres@gmail.com Julio de 2009 #==================================================== import sys import os import random import time import pygame from pygame.locals import * __uso__ = ''' Ayuda: ==================================================================== redoct.py - Un script Python para trabajar con la biblioteca Pygame. -------------------------------------------------------------------- Uso: redoct [opcion] -------------------------------------------------------------------- - Opciones - -h Mostrar ayuda - Teclas de control - a Aumenta la potencia de los motores d Disminuye la potencia de los motores s Detiene las máquinas t, space Dispara torpedos m Dispara misiles 1 Lanza contramedidas de popa 2 Lanza contramedidas de proa ================================================================ ''' XMAX = 800 YMAX = 600 DIRD = '/home/paco/prgdgnu/python/pygame/redoct/datos' TIPO = ['b01.png', 'b02.png', 'b03.png', 'b04.png', 'b05.png', 'b06.png', 'b07.png', 'b08.png'] def cargaImagen(nombre, useColorKey = False): nomf = os.path.join(DIRD, nombre) try: imagen = pygame.image.load(nomf) except pygame.error, message: print "\n\tNo se puede cargar la imagen:", nomf raise SystemExit, message # To speed things up, convert the images to SDL's internal format. imagen = imagen.convert() if useColorKey is True: # Use the color of the pixel located at (0,0) as our colorkey colorkey = imagen.get_at((0,0)) imagen.set_colorkey(colorkey, RLEACCEL) return imagen def cargaSonido(nombre): class NoneSound: def play(self): pass if not pygame.mixer or not pygame.mixer.get_init(): return NoneSound() nomf = os.path.join(DIRD, nombre) try: sonido = pygame.mixer.Sound(nomf) sonido.set_volume(0.5) except pygame.error, mensaje: print "No puedo cargar el fichero de sonido:", nomf raise SystemExit, mensaje return sonido def asignaBuques(buqueSprites): buque = Buque(random.choice(TIPO)) buqueSprites.add(buque) return buqueSprites class ORed(pygame.sprite.Sprite): def __init__(self): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("sub.png", True) self.rect = self.image.get_rect() self.rect.center = (XMAX/2,YMAX-50) self.vx = 0 self.vy = 0 def update(self): self.rect.move_ip((self.vx, self.vy)) if self.rect.right< 0: self.rect.right = XMAX elif self.rect.left > XMAX: self.rect.right = 0 if self.rect.bottom <= (YMAX/2): self.rect.bottom = YMAX/2 elif self.rect.bottom >= YMAX: self.rect.bottom = YMAX class Torpedo(pygame.sprite.Sprite): def __init__(self, x0, y0): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("torpedo.png", True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) def update(self): if self.rect.bottom <= YMAX/2 + 20: self.kill() else: self.rect.move_ip((0, -3)) class Misil(pygame.sprite.Sprite): def __init__(self, x0, y0): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("misil.png", True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) def update(self): if self.rect.bottom < 0: self.kill() else: self.rect.move_ip((0, -5)) class CargaP(pygame.sprite.Sprite): def __init__(self, x0, y0, vc): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("cargap.png", True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) self.vc = vc def update(self): if self.rect.bottom > YMAX - 10: self.kill() else: self.rect.move_ip((0, self.vc)) class Contramedida(pygame.sprite.Sprite): def __init__(self, x0, y0): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("contramedida.png", True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) self.t0 = time.time() def update(self): if int(time.time() - self.t0) > 3: self.kill() class MisilVA(pygame.sprite.Sprite): def __init__(self, x0, y0, vc): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("misilva.png", True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) self.vc = vc def update(self): if self.rect.bottom > YMAX - 10: self.kill() else: self.rect.move_ip((0, self.vc)) class MisilHA(pygame.sprite.Sprite): def __init__(self, tipo, x0, y0, vc): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen(tipo, True) self.rect = self.image.get_rect() self.rect.center = (x0, y0) self.vc = vc def update(self): if self.rect.right < 0 and self.vc < 0: self.kill() elif self.rect.left > XMAX and self.vc > 0: self.kill() else: self.rect.move_ip((self.vc, 0)) class Mina(pygame.sprite.Sprite): def __init__(self): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("mina.png", True) self.rect = self.image.get_rect() x0 = random.randrange(30, XMAX - 30) y0 = random.randrange(YMAX/2 + 150, YMAX - 30) self.rect.center = (x0, y0) class Buque(pygame.sprite.Sprite): def __init__(self, tipo): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen(tipo, True) self.rect = self.image.get_rect() self.nomb = tipo if tipo in TIPO[5:]: s = -1 x0 = XMAX else: s = 1 x0 = 0 self.sentido = s self.rect.center = (x0,YMAX/2 - 30) if tipo in TIPO[2:]: bc = 1 else: bc = 0 self.combate = bc def update(self): self.rect.move_ip((2*self.sentido, 0)) if self.rect.right< 0: self.rect.left = XMAX elif self.rect.left > XMAX: self.rect.right = 0 class Explosion(pygame.sprite.Sprite): def __init__(self, nombre, pos): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen(nombre, True) self.rect = self.image.get_rect() self.rect.center = pos def update(self): self.kill() class Avion(pygame.sprite.Sprite): def __init__(self): # Intialize Sprite, which is our base class pygame.sprite.Sprite.__init__(self) self.image = cargaImagen("avion.png", True) self.rect = self.image.get_rect() x0 = XMAX + 80 y0 = random.randrange(50, YMAX/2 - 60) self.rect.center = (x0, y0) def update(self): if self.rect.right < 0: self.kill() else: self.rect.move_ip((-3, 0)) def main(): try: random.seed() pygame.mixer.pre_init(44100,-16, 2, 1024) pygame.mixer.init() pygame.init() pygame.font.init() fuente = pygame.font.Font(None, 25) screen = pygame.display.set_mode((XMAX, YMAX)) pygame.display.set_caption(' Octubre Rojo ') imagen_fondo = cargaImagen("fondo.png") fondo_rect = imagen_fondo.get_rect() screen.blit(imagen_fondo, (0,0)) # Se crean los contenedores de los Sprites subSprite = pygame.sprite.RenderClear() sub = ORed() subSprite.add(sub) subTorpedoSprites = pygame.sprite.RenderClear() buqueSprites = pygame.sprite.RenderClear() buqueSprites = asignaBuques(buqueSprites) explosionSprites = pygame.sprite.RenderClear() cargaPSprites = pygame.sprite.RenderClear() minaSprites = pygame.sprite.RenderClear() avionSprites = pygame.sprite.RenderClear() misilVASprites = pygame.sprite.RenderClear() misilHASprites = pygame.sprite.RenderClear() subMisilSprites = pygame.sprite.RenderClear() contramedidaSprites = pygame.sprite.RenderClear() # Carga los sonidos torpedoFX = cargaSonido('torpedo.wav') explosion1FX = cargaSonido('explo01.wav') explosion2FX = cargaSonido('explo02.wav') sosFX = cargaSonido('sos.wav') cargapFX = cargaSonido('cargap.wav') subFX = cargaSonido('sub.wav') run = True vx = 0 vy = 0 m = 6 fin = False activo = True clock = pygame.time.Clock() t0 = time.time() puntos = 0 estado = 100 rango = range(30, 1000, 50) vcargas = 1 torpedos = 100 misiles = 100 contramedidas = 50 while run: clock.tick(3*m) t = int(time.time() - t0) eventos = pygame.event.get( ) for e in eventos: if (e.type == QUIT): run = False break elif e.type == KEYDOWN: if e.key == K_ESCAPE or e.key == K_F10: run = False break elif e.key == K_LEFT: vx = - 1 elif e.key == K_RIGHT: vx = 1 elif e.key == K_UP: vy = - 1 elif e.key == K_DOWN: vy = 1 elif e.key == K_a: if m < 10: m = m + 1 elif e.key == K_d: if m > 1 : m = m - 1 elif e.key == K_s: vx = 0 vy = 0 subFX.play() elif e.key == K_t or e.key == K_SPACE: if torpedos > 0: subTorpedoSprites.add(Torpedo(sub.rect.left+100, sub.rect.top)) torpedoFX.play() torpedos -= 1 elif e.key == K_m: if misiles > 0: subMisilSprites.add(Misil(sub.rect.left + 25, sub.rect.top)) torpedoFX.play() misiles -= 1 elif e.key == K_1: if contramedidas > 0: contramedidaSprites.add(Contramedida(sub.rect.centerx - 80, sub.rect.centery + 7)) contramedidas -= 1 elif e.key == K_2: if contramedidas > 0: contramedidaSprites.add(Contramedida(sub.rect.centerx + 90, sub.rect.centery + 7)) contramedidas -= 1 elif e.key == K_f : pygame.display.toggle_fullscreen() if m > 9: m = 9 if m < 1: m = 1 if m > 3 and vx == -1: m = 3 if activo: sub.vx = vx sub.vy = vy # Actualiza todos los Sprites subSprite.update() subTorpedoSprites.update() buqueSprites.update() explosionSprites.update() cargaPSprites.update() avionSprites.update() misilVASprites.update() misilHASprites.update() subMisilSprites.update() contramedidaSprites.update() # Detecta las colisiones entre Sprites: buques - torpedo for colision in pygame.sprite.groupcollide(buqueSprites, subTorpedoSprites, 1, 1): explosionSprites.add(Explosion('explo02.png', colision.rect.center)) explosion2FX.play() puntos += 10 if len(buqueSprites) < 5: buqueSprites = asignaBuques(buqueSprites) # Detecta las colisiones entre Sprites: avión - misil for colision in pygame.sprite.groupcollide(avionSprites, subMisilSprites, 1, 1): explosionSprites.add(Explosion('explo01.png', colision.rect.center)) explosion1FX.play() puntos += 30 # Lanzamiento de cargas de profundidad for b in buqueSprites.sprites(): if b.combate == 1 and abs(sub.rect.centerx - b.rect.centerx ) == sub.rect.width - 30: #sub.rect.centerx in [b.rect.centerx - 30, b.rect.centerx + 30] : cargapFX.play() if b.sentido == -1: cargaPSprites.add(CargaP(b.rect.right + 5, b.rect.top + 10, vcargas)) if b.nomb in ['b03.png', 'b06.png']: cargaPSprites.add(CargaP(b.rect.left - 5, b.rect.top + 10, vcargas)) if b.sentido == 1: cargaPSprites.add(CargaP(b.rect.left - 5, b.rect.top + 10, vcargas)) if b.nomb in ['b03.png', 'b06.png']: cargaPSprites.add(CargaP(b.rect.right + 5, b.rect.top + 10, vcargas)) # Lanzamiento de las cargas de profundidad por el avión for a in avionSprites.sprites(): if n == 103 : misilVASprites.add(MisilVA(a.rect.centerx, a.rect.bottom +15, vcargas + 1)) # Explosión de las cargas de profundidad for c in cargaPSprites.sprites(): if c.rect.centery in [sub.rect.centery - 5, sub.rect.centery + 5]: explosionSprites.add(Explosion('explo01.png', c.rect.center)) c.kill() explosion1FX.play() if abs(c.rect.centerx - sub.rect.centerx) < 100: estado -= 20 elif abs(c.rect.centerx - sub.rect.centerx) < 150: estado -= 10 # Localización y seguimiento de las cargas de profundidad del avión al submarino for misil in misilVASprites.sprites(): if misil.rect.centery in [sub.rect.centery - 5, sub.rect.centery + 5]: x = misil.rect.centerx y = misil.rect.centery misil.kill() if x > sub.rect.centerx: misilHASprites.add(MisilHA('misilhi.png', x, y + 7, -(vcargas + 2))) else: misilHASprites.add(MisilHA('misilhd.png', x, y + 7, vcargas + 2)) # Detecta las colisiones entre Sprites: submarino - cargas for colision in pygame.sprite.groupcollide(cargaPSprites, subSprite, 1, 1): explosionSprites.add(Explosion('explo02.png', colision.rect.center)) explosion2FX.play() fin = True tf = time.time() # Detecta las colisiones entre Sprites: submarino - minas for colision in pygame.sprite.groupcollide(minaSprites, subSprite, 1, 1): explosionSprites.add(Explosion('explo02.png', colision.rect.center)) explosion2FX.play() fin = True tf = time.time() # Detecta las colisiones entre Sprites: submarino - misilha for colision in pygame.sprite.groupcollide(misilHASprites, subSprite, 1, 1): explosionSprites.add(Explosion('explo02.png', colision.rect.center)) explosion2FX.play() fin = True tf = time.time() # Detecta las colisiones entre Sprites: cargas - minas for colision in pygame.sprite.groupcollide(minaSprites, cargaPSprites, 1, 1): explosionSprites.add(Explosion('explo01.png', colision.rect.center)) explosion1FX.play() # Detecta las colisiones entre Sprites: contramedidas - misilha for colision in pygame.sprite.groupcollide(misilHASprites, contramedidaSprites, 1, 1): explosionSprites.add(Explosion('explo01.png', colision.rect.center)) explosion1FX.play() # Limpia la pantalla y dibuja de nuevo subSprite.clear(screen, imagen_fondo) subSprite.draw(screen) subTorpedoSprites.clear(screen, imagen_fondo) subTorpedoSprites.draw(screen) buqueSprites.clear(screen, imagen_fondo) buqueSprites.draw(screen) explosionSprites.clear(screen, imagen_fondo) explosionSprites.draw(screen) cargaPSprites.clear(screen, imagen_fondo) cargaPSprites.draw(screen) minaSprites.clear(screen, imagen_fondo) minaSprites.draw(screen) avionSprites.clear(screen, imagen_fondo) avionSprites.draw(screen) misilVASprites.clear(screen, imagen_fondo) misilVASprites.draw(screen) misilHASprites.clear(screen, imagen_fondo) misilHASprites.draw(screen) subMisilSprites.clear(screen, imagen_fondo) subMisilSprites.draw(screen) contramedidaSprites.clear(screen, imagen_fondo) contramedidaSprites.draw(screen) # Nivel de dificultad n = random.randrange(0, 299) if n == 101: avionSprites.add(Avion()) if puntos in rango: buqueSprites = asignaBuques(buqueSprites) for i in range(puntos/100): minaSprites.add(Mina()) rango = rango[1:] if puntos > 300: vcargas = 2 elif puntos > 700: vcargas = 3 # Información en pantalla datos1 = ' P = ' + str(m) + ' Vx = ' + str(sub.vx) + ' Vy = ' + str(sub.vy) + ' tiempo: ' + str(t) datos2 = ' Puntos: ' + str(puntos) + ' E: ' + str(estado) + ' h = ' + str(sub.rect.bottom - 300) datos3 = ' T = ' + str(torpedos) + ' M = ' + str(misiles) + ' C = ' + str(contramedidas) +' ' texto = fuente.render(datos1 + ' ' + datos2 + ' ' + datos3, 1, (255, 0, 255), (0, 0, 255)) screen.blit(texto, (3, 3)) if estado < 0: sub.vx = 0 sub.vy = 3 if (t % 30) == 0: sosFX.play() activo = False if fin: texto = fuente.render(' - Octubre Rojo cazado ... Game Over !!! - ', 1, (255, 0, 0), (233, 233, 233)) screen.blit(texto, (XMAX/2 - 180, YMAX/2 - 100)) if time.time() - tf > 10: run = False pygame.display.flip() except pygame.error, mensaje: print "\n\t Error:", mensaje, "\n" except: print "\n\t Error: ", sys.exc_info()[0], "\n" if __name__ == '__main__': if len(sys.argv) == 1: main() elif len(sys.argv) == 2: if sys.argv[1] == '-h': print __uso__