Como ya enseñé en otro hilo, estoy haciendo un juego con una navecita. En este hilo iré posteando los progresos según vaya consiguiendo avances más o menos importantes. De momento cuenta con lo siguiente:
- Nave protagonista
- Misiles para la nave protagonista
- Enemigos aleatorios
De momento se parece mucho al Invaders de Juanxo, aunque tengo pensado hacer algo distinto. Tenía pensado dividir el juego en varias tandas, unas de enemigos aleatorios, como los que hay ahora en las que tuvieras que matar x enemigos sin que se te escape ningno por la parte de abajo de la ventana. Otra con enemigos más fuertes que no se desplacen demasiado pero que disparen. Estos no sería aleatorios si no que irían definidos. Finalmente un enemigo final.
De momento no tengo ninguna duda. Lo único que quiero preguntar es si estoy mezclando demasiado las calses de Nave y Misil. Es que le paso muchos atributos de la clase misil a nave para no tener que cargarlos una y otra vez.

- Código: Seleccionar todo
- #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # ------------------------------
 # Autor: Rafael Álvarez García
 # e-mail: algarafa@gmail.com
 # ------------------------------
 # ------------------------------
 # Importación de módulos
 # ------------------------------
 import pygame
 from pygame.locals import *
 import sys
 import os
 import random
 # ------------------------------
 # Constantes
 # ------------------------------
 SCREEN_WIDTH = 400
 SCREEN_HEIGHT = 600
 IMG_DIR = 'images'
 SOUND_DIR = 'sounds'
 # ------------------------------
 # Funciones y clases
 # ------------------------------
 # Creamos la función para cargar imágenes.
 def load_image(name, dir, alpha = False):
 # Unimos la ruta de la imágen.
 ruta = os.path.join(dir, name)
 # Probamos a cargarla y si no devolvemos error.
 try:
 image = pygame.image.load(ruta)
 print 'Cargando imagen', ruta, '...¡éxito!'
 
 except:
 print 'No se pudo cargar la imagen', ruta
 sys.exit(1)
 
 # Comprobamos si hay alpha.
 if alpha:
 image = image.convert_alpha()
 else:
 image = image.convert()
 
 return image
 
 # Función para cargar sonidos.
 def load_sound(name, dir_sound):
 ruta = os.path.join(dir_sound, name)
 try:
 sound = pygame.mixer.Sound(ruta)
 print 'Cargando sonido', ruta, '...¡éxito!'
 except:
 sound = None
 print 'No se pudo cargar el sonido', ruta
 
 return sound
 # Clase para la nave.
 class Nave(pygame.sprite.Sprite):
 
 def __init__(self, sprites, misiles, misil_img, misil_sound):
 pygame.sprite.Sprite.__init__(self)
 self.image = load_image('nave.png', IMG_DIR, alpha = True)
 self.rect = self.image.get_rect()
 self.sprites = sprites
 self.misiles = misiles
 self.misil_img = misil_img
 self.misil_sound = misil_sound
 self.counter = 0
 self.rect.centerx = SCREEN_WIDTH / 2
 self.rect.centery = SCREEN_HEIGHT - 60
 self.speed = [0, 0]
 
 def update(self):
 # Hacemos que no salga de la pantalla.
 if self.rect.top < 0:
 self.rect.top = 0
 self.speed[1] = 0
 elif self.rect.bottom > SCREEN_HEIGHT + 1:
 self.rect.bottom = SCREEN_HEIGHT
 self.speed[1] = 0
 elif self.rect.left < -1:
 self.rect.left = 0
 self.speed[0] = 0
 elif self.rect.right > SCREEN_WIDTH + 1:
 self.rect.right = SCREEN_WIDTH
 self.speed[0] = 0
 
 # Actualiza el contador para simular la recarga de munición.
 if self.counter > 0:
 self.counter -= 1
 
 self.rect.move_ip(self.speed)
 
 # Indica si podemos disparar o no.
 def can_shoot(self):
 return self.counter == 0
 
 # Dispara los misiles.
 def shoot(self):
 if self.can_shoot():
 misil = Misil(self.rect.midtop, self.misiles, self.misil_img)
 self.sprites.add(misil)
 self.misiles.add(misil)
 self.misil_sound.play()
 # Actualiza el tiempo de recarga.
 self.counter = 40
 
 # Clase para los enemigos.
 class Enemigo(pygame.sprite.Sprite):
 
 def __init__(self, image):
 pygame.sprite.Sprite.__init__(self)
 self.image = image
 self.rect = self.image.get_rect()
 self.generar_pos()
 self.generar_vel()
 self.vida = 1
 
 def update(self):
 if self.rect.left < 0:
 self.speed[0] = -self.speed[0]
 if self.rect.right > SCREEN_WIDTH:
 self.speed[0] = -self.speed[0]
 
 # Si se queda sin vida o si sale de pantalla lo matamos.
 if self.vida == 0:
 self.kill()
 if self.rect.top == SCREEN_HEIGHT:
 self.kill()
 
 self.rect.move_ip(self.speed)
 
 
 def generar_pos(self):
 # Genera uns posición de x aleatoria.
 pos = random.randrange(50, SCREEN_WIDTH -50)
 self.rect.centerx = pos
 self.rect.centery = 25
 
 def generar_vel(self):
 # Genera una velocidad aleatoria.
 x = random.randrange(-5, 5)
 y = random.randrange(1, 3)
 self.speed = [x, y]
 
 # Clase para el misil.
 class Misil(pygame.sprite.Sprite):
 
 def __init__(self, initial_pos, misiles, image):
 pygame.sprite.Sprite.__init__(self)
 self.image = image
 self.rect = self.image.get_rect()
 self.rect.midbottom = initial_pos
 self.speed = [0, -4]
 self.poder_destruccion = 1
 misiles.add(self)
 
 # Si se sale de pantalla lo matamos, si no lo movemos.
 def update(self):
 if self.rect.bottom < 0:
 self.kill
 else:
 self.rect.move_ip(self.speed)
 
 # Comprobamos las colisiones con enemigos.
 def colisiones(self, objetivos): # Objetivos debe ser una lista.
 for objetivo in objetivos:
 if self.rect.colliderect(objetivo):
 objetivo.vida -= self.poder_destruccion
 self.kill()
 
 # ------------------------------
 # Función principal
 # ------------------------------
 def main():
 pygame.init()
 pygame.mixer.init()
 print 'Iniciando juego...'
 
 # Creamos la ventana e indicamos nombre e icono.
 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
 pygame.display.set_caption('Provisional')
 icon = pygame.image.load('images/nave.png').convert_alpha()
 pygame.display.set_icon(icon)
 print 'Creando ventana... ¡éxito!'
 
 # Cargamos e imprimimos el fondo.
 fondo = load_image('background.jpg', IMG_DIR)
 screen.blit(fondo, (0, 0))
 
 # Cargamos las imágenes y sonidos que usaremos mucho para no tener
 # que cargarlas cada vez que creemos un objeto de esa clase.
 misil_img = load_image('misil.png', IMG_DIR, alpha = True)
 misil_sound = load_sound('misil.wav', SOUND_DIR)
 enemigo_img = load_image('enemigo.png', IMG_DIR, alpha = True)
 
 # Cremoas el frupo de sprites.
 sprites = pygame.sprite.Group()
 
 # Creamos un contador para los enemigos aleatorios.
 contador = 0
 
 # Creamos un grupo para los misiles y otra para los enemigos.
 misiles = pygame.sprite.Group()
 enemigos = pygame.sprite.Group()
 
 # Creamos la nave y la añadimos al grupo sprites.
 nave = Nave(sprites, misiles, misil_img, misil_sound)
 sprites.add(nave)
 
 # Creamos el reloj.
 clock = pygame.time.Clock()
 # Activamos la repetición de teclas.
 pygame.key.set_repeat(1, 25)
 # Hacemos el ratón invisible.
 pygame.mouse.set_visible(False)
 
 # Bucle principal.
 while True:
 clock.tick(60)
 
 # Comprobamos los eventos.
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
 print 'Cerrando juego...'
 sys.exit()
 
 if event.type == pygame.KEYDOWN:
 if event.key == K_UP:
 nave.speed[1] -= 0.3
 elif event.key == K_DOWN:
 nave.speed[1] += 0.3
 elif event.key == K_LEFT:
 nave.speed[0] -= 0.3
 elif event.key == K_RIGHT:
 nave.speed[0] += 0.3
 elif event.key == K_SPACE:
 nave.shoot()
 
 elif event.key == K_ESCAPE:
 print 'Cerrando juego...'
 sys.exit()
 
 # Actualizamos el contador de enemigos aleatorios.
 if contador > 0:
 contador -= 1
 
 # Generamos los enemigos aleatorios.
 if contador == 0:
 enemigo = Enemigo(enemigo_img)
 sprites.add(enemigo)
 enemigos.add(enemigo)
 contador = 100
 
 # Comprobamos las colisiones.
 for misil in misiles:
 misil.colisiones(enemigos)
 
 # Actualizamos los sprites.
 sprites.update()
 
 # Actualizamos la pantalla.
 sprites.clear(screen, fondo)
 sprites.draw(screen)
 pygame.display.flip()
 
 if __name__ == "__main__":
 main()
En próximos posts pondré un link de descarga para que no tengáis que buscar imágenes para probarlo. Es que le quiero buscar un nombre para crearle una página dentro de mi blog y así ir subiendolo periódicamente.
¡Un saludo!
 
 P.D.: Cuando el juego esté listo, losersjuegos tendrá su lugar em los créditos

























