Incluimos sonido 'al vuelo'
This commit is contained in:
parent
af11922320
commit
101699b4a6
@ -1,9 +1,13 @@
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
import array
|
||||
import random
|
||||
import pygame
|
||||
|
||||
# Inicialización de Pygame y el mezclador de audio
|
||||
pygame.init()
|
||||
pygame.mixer.init(frequency=22050, size=-16, channels=1)
|
||||
|
||||
# Configuración de Pantalla
|
||||
SCREEN_WIDTH = 800
|
||||
@ -31,6 +35,56 @@ COLOR_ORANGE = (255, 140, 0)
|
||||
COLOR_CYAN = (0, 200, 255)
|
||||
|
||||
|
||||
def generate_sound(sound_type):
|
||||
"""Genera efectos de sonido retro de forma sintética sin archivos externos."""
|
||||
sample_rate = 22050
|
||||
buffer = array.array("h")
|
||||
|
||||
if sound_type == "shoot":
|
||||
# Disparo: Tono descendente agudo rápido
|
||||
duration = 0.1
|
||||
total_samples = int(sample_rate * duration)
|
||||
for i in range(total_samples):
|
||||
t = i / total_samples
|
||||
freq = 800 * (1 - t * 0.7)
|
||||
val = math.sin(2 * math.pi * freq * (i / sample_rate))
|
||||
env = 1 - t
|
||||
sample = int(val * env * 12000)
|
||||
buffer.append(sample)
|
||||
|
||||
elif sound_type == "hit":
|
||||
# Choque: Golpe sordo de baja frecuencia
|
||||
duration = 0.15
|
||||
total_samples = int(sample_rate * duration)
|
||||
for i in range(total_samples):
|
||||
t = i / total_samples
|
||||
freq = 150 * (1 - t * 0.5)
|
||||
noise = (random.random() * 2 - 1) * 0.3
|
||||
val = math.sin(2 * math.pi * freq * (i / sample_rate)) + noise
|
||||
env = (1 - t) ** 2
|
||||
sample = int(val * env * 15000)
|
||||
buffer.append(max(-32768, min(32767, sample)))
|
||||
|
||||
elif sound_type == "destroy":
|
||||
# Destrucción: Ruido de explosión corta
|
||||
duration = 0.2
|
||||
total_samples = int(sample_rate * duration)
|
||||
for i in range(total_samples):
|
||||
t = i / total_samples
|
||||
noise = random.random() * 2 - 1
|
||||
env = (1 - t) ** 1.5
|
||||
sample = int(noise * env * 14000)
|
||||
buffer.append(sample)
|
||||
|
||||
return pygame.mixer.Sound(buffer=buffer)
|
||||
|
||||
|
||||
# Cargar sonidos sintéticos
|
||||
SOUND_SHOOT = generate_sound("shoot")
|
||||
SOUND_HIT = generate_sound("hit")
|
||||
SOUND_DESTROY = generate_sound("destroy")
|
||||
|
||||
|
||||
def grid_to_iso(gx, gy, gz=0):
|
||||
"""Convierte coordenadas 3D de rejilla a coordenadas 2D de pantalla."""
|
||||
iso_x = (gx - gy) * (TILE_WIDTH // 2)
|
||||
@ -204,10 +258,10 @@ class Bullet(Entity):
|
||||
and abs(entity.gy - self.gy) < 0.5
|
||||
):
|
||||
self.alive = False
|
||||
SOUND_HIT.play()
|
||||
if isinstance(entity, WhiteBlock):
|
||||
entity.health -= 1
|
||||
elif isinstance(entity, PurpleBlock):
|
||||
# El bloque morado es empujado por el disparo
|
||||
entity.push_by_bullet(self.dir_x, self.dir_y, entities)
|
||||
elif isinstance(entity, Enemy) and entity.destructible:
|
||||
entity.take_damage()
|
||||
@ -250,7 +304,6 @@ class PurpleBlock(Entity):
|
||||
)
|
||||
|
||||
def push_by_bullet(self, dir_x, dir_y, entities):
|
||||
"""Se desplaza 1 casilla entera en la dirección del impacto del disparo."""
|
||||
step_x = 1 if dir_x > 0.3 else (-1 if dir_x < -0.3 else 0)
|
||||
step_y = 1 if dir_y > 0.3 else (-1 if dir_y < -0.3 else 0)
|
||||
|
||||
@ -386,7 +439,6 @@ class Player(Entity):
|
||||
abs(entity.gx - target_gx) < 0.5
|
||||
and abs(entity.gy - target_gy) < 0.5
|
||||
):
|
||||
# Bloque Blanco: Se empuja caminando
|
||||
if isinstance(entity, WhiteBlock):
|
||||
push_dx = (
|
||||
0.15 if dx > 0 else (-0.15 if dx < 0 else 0)
|
||||
@ -396,7 +448,6 @@ class Player(Entity):
|
||||
)
|
||||
if not entity.push(push_dx, push_dy, entities):
|
||||
blocked = True
|
||||
# Bloque Morado y otros elementos: Bloquean el movimiento del jugador
|
||||
else:
|
||||
blocked = True
|
||||
if not blocked:
|
||||
@ -412,6 +463,7 @@ class Player(Entity):
|
||||
bullets.append(
|
||||
Bullet(spawn_x, spawn_y, self.facing_x, self.facing_y)
|
||||
)
|
||||
SOUND_SHOOT.play()
|
||||
self.shoot_cooldown = 15
|
||||
|
||||
|
||||
@ -420,6 +472,7 @@ class Vortex(Entity):
|
||||
def __init__(self, gx, gy):
|
||||
super().__init__(gx, gy, "vortex", "vortex.png", is_solid=True)
|
||||
self.speed = 0.012
|
||||
self.was_blocked = False
|
||||
|
||||
def update(self, entities):
|
||||
target_gy = self.gy - self.speed
|
||||
@ -434,6 +487,11 @@ class Vortex(Entity):
|
||||
blocked = True
|
||||
break
|
||||
|
||||
if blocked and not self.was_blocked:
|
||||
SOUND_HIT.play()
|
||||
|
||||
self.was_blocked = blocked
|
||||
|
||||
if not blocked and target_gy >= 0:
|
||||
self.gy = target_gy
|
||||
|
||||
@ -472,9 +530,7 @@ class Game:
|
||||
)
|
||||
self.spares.append(spare)
|
||||
|
||||
# Generar mapa balanceado con bloques blancos y morados
|
||||
for y in range(10, GRID_SIZE_Y - 12):
|
||||
# Alternar entre bloques Blancos (empujables) y Morados (desplazados por disparos)
|
||||
if y % 6 == 0:
|
||||
lane = (y * 3) % GRID_SIZE_X
|
||||
if (y // 6) % 2 == 0:
|
||||
@ -504,12 +560,13 @@ class Game:
|
||||
)
|
||||
|
||||
if player_hit or vortex_hit:
|
||||
SOUND_DESTROY.play()
|
||||
return True
|
||||
|
||||
# Eliminar bloques blancos destruidos y enemigos abatidos
|
||||
for entity in self.entities[:]:
|
||||
if hasattr(entity, "health") and entity.health <= 0:
|
||||
self.entities.remove(entity)
|
||||
SOUND_DESTROY.play()
|
||||
self.score += 200
|
||||
|
||||
return False
|
||||
|
||||
BIN
img-versiones/version_4.1.png
Normal file
BIN
img-versiones/version_4.1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Loading…
x
Reference in New Issue
Block a user