Juego con PyGame con Detección de Sonido con Microfono

El objetivo de este proyecto es crear un videojuego pequeño con Python y la libreria de PyGame. El videojuego consiste en un personaje que lo mueves mediante tu voz con un microfono, el personaje se movera constantemente hacia la izquierda pero cuando se detecte un sonido el personaje se movera hacia la derecha. Tambien tendras que esquivar unos asteroides que aparecen aleatoriamente del cielo.

Requisitos: Python con las librerias pygame, pyaudio, numpy y random. Un editor de texto o un IDE para poder escribir el codigo y un microfono conectado al ordenador.

Paso 1: Instalacion de los requerimientos

sudo apt update
sudo apt install python3 
sudo apt install python3-venv
mkdir juego_microfono
cd juego_microfono
python3 -m venv entorno_microfono
source entorno_microfono/bin/activate 
sudo apt-get install portaudio19-dev python3-pyaudio python3-pyaudio
pip install pygame
pip install pyaudio
pip install numpy
pip install random

Paso 2: Creacion del juego

El codigo python del juego es el siguiente, copialo en un archivo y guardalo como juego_micro.py

import pygame
import pyaudio
import numpy as np
import random

# Inicializar pygame
pygame.init()

# Configuración de la ventana
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Juego con micrófono")

# Cargar imagen de fondo
background_image = pygame.image.load("fondo.png")
background_image = pygame.transform.scale(background_image, (screen_width, screen_height))  # Ajustar al tamaño de la ventana

# Cargar imágenes del jugador
alien_left = pygame.image.load("alien_izquierda.png")
alien_right = pygame.image.load("alien_derecha.png")
alien_width = alien_left.get_width()
alien_height = alien_left.get_height()

# Cargar imagen del asteroide
asteroid_image = pygame.image.load("asteroide.png")
asteroid_width = asteroid_image.get_width()
asteroid_height = asteroid_image.get_height()

# Posición inicial del jugador
square_x = screen_width // 2 - alien_width // 2
square_y = screen_height // 2 - alien_height // 2
square_speed = 5  # Velocidad de movimiento inicial

# Lista de asteroides que caen
asteroids = []

# Reloj para controlar la velocidad del juego
clock = pygame.time.Clock()

# Configuración del micrófono con PyAudio
THRESHOLD = 1000  # Umbral para considerar que se está recibiendo sonido
CHUNK_SIZE = 512  # Tamaño del fragmento de audio
RATE = 44124  # Frecuencia de muestreo

# Configuración de PyAudio
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16,
                channels=1,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK_SIZE)

# Función para leer datos del micrófono
def get_microphone_data():
    data = np.frombuffer(stream.read(CHUNK_SIZE), dtype=np.int16)
    volume = np.max(np.abs(data))
    return volume

# Función para comprobar colisiones
def check_collision(rect1, rect2):
    return rect1.colliderect(rect2)

# Función para reiniciar el juego
def reset_game():
    global square_x, square_y, asteroids, running, game_over, start_ticks, square_speed, spawn_probability
    square_x = screen_width // 2 - alien_width // 2
    square_y = screen_height // 2 - alien_height // 2
    asteroids = []
    game_over = False  # Reiniciar el estado del juego
    start_ticks = pygame.time.get_ticks()  # Reiniciar el temporizador
    square_speed = 5  # Restablecer la velocidad
    spawn_probability = 0.02  # Restablecer la probabilidad de aparición de asteroides

# Bucle principal del juego
running = True
game_over = False  # Variable para controlar si el juego está en estado de "perdido"

# Reiniciar el temporizador cuando el juego comienza
start_ticks = pygame.time.get_ticks()

# Tiempo de incremento de velocidad y probabilidad de aparición de asteroides
last_speed_increase_time = pygame.time.get_ticks()
spawn_probability = 0.10  # Probabilidad inicial de que aparezca un asteroide

while running:
    # Manejo de eventos
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and game_over:  # Reiniciar juego si presionas la barra espaciadora
                reset_game()

    if game_over:
        # Si el juego ha terminado, mostrar el mensaje de "Perdiste" y esperar a que el jugador reinicie
        screen.blit(background_image, (0, 0))  # Dibujar el fondo
        font = pygame.font.Font(None, 54)
        text = font.render("¡Perdiste! Presiona Espacio para Reiniciar", True, (255, 255, 255))
        score = font.render(f"Puntuacion: {seconds}", True, (255, 255, 255))
        text_rect = text.get_rect(center=(screen_width // 2, screen_height // 2))  # Centrar el texto
        screen.blit(text, text_rect)
        pygame.display.flip()
        continue

    # Obtener datos del micrófono
    volume = get_microphone_data()

    # Si se detecta sonido, mover el jugador a la derecha
    if volume > THRESHOLD:
        square_x += square_speed
        if square_x + alien_width > screen_width:  # Asegura que no se salga de la pantalla
            game_over = True
            square_x = screen_width - alien_width
        current_image = alien_right
    else:
        square_x -= square_speed
        if square_x < 0:  # Asegura que no se salga de la pantalla
            game_over = True
            square_x = 0
        current_image = alien_left

    # Agregar nuevos asteroides de forma aleatoria
    if random.random() < spawn_probability:  # Probabilidad de que un asteroide caiga
        asteroid_x = random.randint(0, screen_width - asteroid_width)
        asteroids.append(pygame.Rect(asteroid_x, 0, asteroid_width, asteroid_height))

    # Actualizar la posición de los asteroides
    for asteroid in asteroids[:]:
        asteroid.y += 5  # Caen hacia abajo

        # Si un asteroide colisiona con el jugador, termina el juego
        player_rect = pygame.Rect(square_x, square_y, alien_width, alien_height)
        if check_collision(asteroid, player_rect):
            game_over = True  # El juego termina cuando hay colisión

        # Eliminar asteroides que llegan al fondo
        if asteroid.y > screen_height:
            asteroids.remove(asteroid)

    # Comprobar si han pasado 5 segundos para aumentar la velocidad y la probabilidad de aparición de asteroides
    current_time = pygame.time.get_ticks()
    if current_time - last_speed_increase_time >= 5000:  # 5000 ms = 5 segundos
        square_speed += 3  # Aumentar la velocidad
        spawn_probability += 0.01  # Aumentar la probabilidad de aparición de asteroides
        last_speed_increase_time = current_time  # Actualizar el tiempo del último aumento

    # Limpiar la pantalla y dibujar el fondo
    screen.blit(background_image, (0, 0))  # Dibujar el fondo

    # Dibujar los asteroides
    for asteroid in asteroids:
        screen.blit(asteroid_image, (asteroid.x, asteroid.y))

    # Dibujar el jugador con la imagen correspondiente
    screen.blit(current_image, (square_x, square_y))

    # Calcular el tiempo transcurrido y mostrarlo como puntaje
    seconds = (pygame.time.get_ticks() - start_ticks) // 1000  # Convertir el tiempo a segundos
    font = pygame.font.Font(None, 36)
    score_text = font.render(f"Score: {seconds}", True, (255, 255, 255))
    screen.blit(score_text, (screen_width - 150, 10))  # Mostrar puntaje en la esquina superior derecha

    # Actualizar la pantalla
    pygame.display.flip()

    # Controlar la velocidad del juego
    clock.tick(30)

# Detener el stream y cerrar PyAudio al finalizar
stream.stop_stream()
stream.close()
p.terminate()

# Salir de pygame
pygame.quit()

Paso 3. Descarga de imagenes necesarias y ejecución

Necesitamos descargar los sprites y fondo del juego, para ello haremos lo siguiente:

wget http://openwrt.tuinstituto.es/wp-content/uploads/2025/03/images.zip
unzip images.zip

Lo ejecutamos con:

python3 juego_micro.py

Debes tener en cuenta que cada vez que ejecutes el juego debes entrar en el entorno virtual:

cd juego_microfono
source entorno_microfono/bin/activate
python3 juego_micro.py

Tendras que tener unas imagenes para el fondo, el personaje y para los objetos que caigan del cielo, si tienes unos nombres de imagenes diferente solo tienes que ir a la parte del codigo donde se carguen las imagenes y cambiar el nombre entre los ” a el nombre de imagen que tengas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

+ 87 = 94