Curso Python. Volumen XXI: Pygame, videojuegos en python. Parte IX

Escrito por Javier Ceballos Fernández
Programación

Bienvenidos un día más al curso de Python. En el capítulo anterior os enseñamos como crear un jugador ficticio para por lo menos poder jugar contra el ordenador. En este capítulo, vamos a agregar sonido al videojuego que estamos realizando con la popular librería “Pygame”. Así que pongámonos manos a la obra.

Sonido

Para agregar los sonidos tendremos que hacer las siguientes modificaciones al código:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ---------------------------
# Importacion de los módulos
# ---------------------------

import pygame
from pygame.locals import *
import os
import sys

# -----------
# Constantes
# -----------

SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
IMG_DIR = "imagenes"
SONIDO_DIR = "sonidos"

# ------------------------------
# Clases y Funciones utilizadas
# ------------------------------


def load_image(nombre, dir_imagen, alpha=False):
    # Encontramos la ruta completa de la imagen
    ruta = os.path.join(dir_imagen, nombre)
    try:
        image = pygame.image.load(ruta)
    except:
        print("Error, no se puede cargar la imagen: " + ruta)
        sys.exit(1)
    # Comprobar si la imagen tiene "canal alpha" (como los png)
    if alpha is True:
        image = image.convert_alpha()
    else:
        image = image.convert()
    return image


def load_sound(nombre, dir_sonido):
    ruta = os.path.join(dir_sonido, nombre)
    # Intentar cargar el sonido
    try:
        sonido = pygame.mixer.Sound(ruta)
    except (pygame.error) as message:
        print("No se pudo cargar el sonido:", ruta)
        sonido = None
    return sonido

# -----------------------------------------------
# Creamos los sprites (clases) de los objetos del juego:


class Pelota(pygame.sprite.Sprite):
    "La bola y su comportamiento en la pantalla"

    def __init__(self, sonido_golpe, sonido_punto):
        pygame.sprite.Sprite.__init__(self)
        self.image = load_image("bola.png", IMG_DIR, alpha=True)
        self.rect = self.image.get_rect()
        self.rect.centerx = SCREEN_WIDTH / 2
        self.rect.centery = SCREEN_HEIGHT / 2
        self.speed = [3, 3]
        self.sonido_golpe = sonido_golpe
        self.sonido_punto = sonido_punto

    def update(self):
        if self.rect.left < 0 or self.rect.right > SCREEN_WIDTH:
            self.speed[0] = -self.speed[0]
            self.sonido_punto.play()  # Reproducir sonido de punto
        if self.rect.top < 0 or self.rect.bottom > SCREEN_HEIGHT:
            self.speed[1] = -self.speed[1]
        self.rect.move_ip((self.speed[0], self.speed[1]))

    def colision(self, objetivo):
        if self.rect.colliderect(objetivo.rect):
            self.speed[0] = -self.speed[0]
            self.sonido_golpe.play()  # Reproducir sonido de rebote


class Paleta(pygame.sprite.Sprite):
    "Define el comportamiento de las paletas de ambos jugadores"

    def __init__(self, x):
        pygame.sprite.Sprite.__init__(self)
        self.image = load_image("paleta.png", IMG_DIR, alpha=True)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = SCREEN_HEIGHT / 2

    def humano(self):
        # Controlar que la paleta no salga de la pantalla
        if self.rect.bottom >= SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT
        elif self.rect.top <= 0: self.rect.top = 0 def cpu(self, objetivo): self.rect.centery = objetivo.rect.centery if self.rect.bottom >= SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT
        elif self.rect.top <= 0:
            self.rect.top = 0

# ------------------------------
# Funcion principal del juego
# ------------------------------


def main():
    pygame.init()
    pygame.mixer.init()
    # creamos la ventana y le indicamos un titulo:
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Pong")

    # cargamos los objetos
    fondo = load_image("fondo.jpg", IMG_DIR, alpha=False)
    sonido_golpe = load_sound("tennis.ogg", SONIDO_DIR)
    sonido_punto = load_sound("aplausos.ogg", SONIDO_DIR)

    bola = Pelota(sonido_golpe, sonido_punto)
    jugador1 = Paleta(40)
    jugador2 = Paleta(SCREEN_WIDTH - 40)

    clock = pygame.time.Clock()
    pygame.key.set_repeat(1, 25)  # Activa repeticion de teclas
    pygame.mouse.set_visible(False)

    # el bucle principal del juego
    while True:
        clock.tick(60)
        # Obtenemos la posicion del raton
        pos_mouse = pygame.mouse.get_pos()
        mov_mouse = pygame.mouse.get_rel()

        # Actualizamos los objetos en pantalla
        jugador1.humano()
        jugador2.cpu(bola)
        bola.update()

        # Comprobamos si colisionan los objetos
        bola.colision(jugador1)
        bola.colision(jugador2)

        # Posibles entradas del teclado y raton
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == K_UP:
                    jugador1.rect.centery -= 5
                elif event.key == K_DOWN:
                    jugador1.rect.centery += 5
                elif event.key == K_ESCAPE:
                    sys.exit(0)
            elif event.type == pygame.KEYUP:
                if event.key == K_UP:
                    jugador1.rect.centery += 0
                elif event.key == K_DOWN:
                    jugador1.rect.centery += 0
            # Si el raton no esta quieto, mover la paleta a su posicion
            elif mov_mouse[1] != 0:
                jugador1.rect.centery = pos_mouse[1]

        # actualizamos la pantalla
        screen.blit(fondo, (0, 0))
        screen.blit(bola.image, bola.rect)
        screen.blit(jugador1.image, jugador1.rect)
        screen.blit(jugador2.image, jugador2.rect)
        pygame.display.flip()

if __name__ == "__main__":
    main()

Lo primero que hemos realizado ha sido crear una función que cargue los sonidos “load_sound”, es muy parecida a la función de cargar imágenes. Para abrir el archivo usamos el módulo “pygame.mixer.Sound” abriendo el sonido de la forma “sonido = pygame.mixer.Sound(ruta)”

Después tenemos que iniciar el modulo “mixer”, que es el que se encarga de los sonidos, dentro del bucle principal haciendo “pygame.mixer.init()”. Una vez realizado esto, simplemente tenemos que cargar los sonidos usando la función que hemos creado anteriormente, es decir:

sonido_golpe = load_sound("tennis.ogg", SONIDO_DIR)
sonido_punto = load_sound("aplausos.ogg", SONIDO_DIR)

Estos sonidos se los tendremos que pasar a la clase “pelota” haciendo “bola = Pelota(sonido_golpe, sonido_punto)”. Dentro de la clase pelota estos sonidos se almacenan en “self.sonido_golpe” y “self.sonido_punto”.

En la clase de la pelota usaremos “Sound.play()” para que se reproduzcan los sonidos. Así en el método “colision()” se le indica que si la pelota colisiona con una paleta reproduzca el archivo “tennis.ogg”, que fue guardado en “self.sonido_golpe”, haciendo “self.sonido_golpe.play()” y en el método “update()” al llegar a los bordes izquierdo y derecho de la pantalla se reproduce unos aplausos haciendo “self.sonido_punto.play()”.

Aquí lo dejamos por hoy, os recomendamos que hagáis un repaso de lo aprendido por el momento y que experimentéis.

En el próximo capítulo haremos unas mejoras en nuestro videojuego de modo que mejoremos su rendimiento y además haremos que el jugador ficticio que creamos en el capítulo anterior pueda perder.

Comentaros como siempre, que todos los que se acaban de incorporar al curso tienen un índice con todos los capítulos del curso, ya que nunca es tarde para empezar.

Fuente > GitHub dbfuentes


Últimos análisis

Valoración RZ
8
Valoración RZ
9
Valoración RZ
9
Valoración RZ
10
Valoración RZ
9
Valoración RZ
10
Valoración RZ
7
Valoración RZ
9
Valoración RZ
10
Valoración RZ
8