I'm making a game in Pygame running in Python 3.10 and the lastest version of pygame, and I can't get to display a volume control for the background music . The music is played correctly, but there is no volume control
import pygame
import random
# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Genesis Breaker: Legioss Shmup")
clock = pygame.time.Clock()
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# MUSICA
pygame.mixer.init()
music_list = ["Space Life.mp3", "The Future is coming.mp3", "Danger Sector.mp3"]
current_music = random.choice(music_list)
pygame.mixer.music.load(current_music)
pygame.mixer.music.set_volume(0.5) # 50% volume
pygame.mixer.music.play(-1) # Loop indefinitely
music_volume = 0.5 # Initial volume (50%)
volume_display_timer = 0 # Timer for volume display
pygame.mixer.music.set_volume(music_volume)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_f:
bullets.extend(legioss.shoot())
elif event.key == pygame.K_PLUS or event.key == pygame.K_EQUALS: # + or = key
music_volume = min(music_volume + 0.1, 1.0)
pygame.mixer.music.set_volume(music_volume)
volume_display_timer = pygame.time.get_ticks()
elif event.key == pygame.K_MINUS: # - key
music_volume = max(music_volume - 0.1, 0.0)
pygame.mixer.music.set_volume(music_volume)
volume_display_timer = pygame.time.get_ticks()
elif event.key == pygame.K_PAGEUP: # Page Up
music_volume = min(music_volume + 0.1, 1.0)
pygame.mixer.music.set_volume(music_volume)
volume_display_timer = pygame.time.get_ticks()
elif event.key == pygame.K_PAGEDOWN: # Page Down
music_volume = max(music_volume - 0.1, 0.0)
pygame.mixer.music.set_volume(music_volume)
volume_display_timer = pygame.time.get_ticks()
font = pygame.font.SysFont('arial', 24)
volume_bg = pygame.Surface((120, 60), pygame.SRCALPHA)
volume_bg.fill((0, 0, 0, 100))
screen.blit(volume_bg, (5, 165))
pygame.draw.rect(screen, (255, 0, 0), (10, 200, 100, 20), 1)
pygame.draw.rect(screen, WHITE, (10, 200, 100, 20), 2)
pygame.draw.rect(screen, (0, 255, 0), (12, 202, 96 * music_volume, 16))
volume_instruction = font.render("Usa PgUp/PgDn para ajustar volumen", True, WHITE)
screen.blit(volume_instruction, (10, 220))
if pygame.time.get_ticks() - volume_display_timer < 2000:
volume_text = font.render(f"Volumen: {int(music_volume * 100)}%", True, WHITE)
screen.blit(volume_text, (10, 170))
##################### FIN MUSICA ##########################################################
legioss_fighter = pygame.image.load("legioss_fighter.png")
legioss_fighter = pygame.transform.scale(legioss_fighter, (80, 100))
legioss_diver = pygame.Surface((64, 64))
legioss_diver.fill((100, 255, 100)) # Green for Diver
legioss_soldier = pygame.Surface((64, 64))
legioss_soldier.fill((255, 100, 100)) # Red for Soldier
tread_bomber = pygame.Surface((128, 64))
tread_bomber.fill((200, 200, 200)) # Gray for Bulldog
invid_frames = [
pygame.transform.scale(pygame.image.load("invid1.png").convert_alpha(), (72, 72)),
pygame.transform.scale(pygame.image.load("invid2.png").convert_alpha(), (72, 72)),
pygame.transform.scale(pygame.image.load("invid3.png").convert_alpha(), (72, 72))
]
background_img = pygame.image.load("starfield.png")
background_img = pygame.transform.scale(background_img, (800, 1200))
napalm_img = pygame.Surface((32, 32))
napalm_img.fill((255, 150, 0)) # Orange for napalm
# Classes
class Legioss:
def __init__(self):
self.collision_timer = 0
self.modes = [legioss_fighter, legioss_diver, legioss_soldier]
self.mode = 0
self.image = self.modes[self.mode]
#self.rect = self.image.get_rect(topleft=(400, 500))
self.rect = self.image.get_rect(topleft=(400, 400))
self.speed = 6
self.shoot_delay = 0
self.tread_active = False
self.tread_timer = 0
self.energy = 100
self.energy_timer = pygame.time.get_ticks()
def move(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.x > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.x < 800 - self.rect.width:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.y > 0: # Changed from 300 to 0
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.y < 600 - self.rect.height:
self.rect.y += self.speed
if keys[pygame.K_SPACE] and pygame.time.get_ticks() - self.shoot_delay > 500 and self.energy >= 20:
self.mode = (self.mode + 1) % 3
self.image = self.modes[self.mode]
self.rect = self.image.get_rect(center=self.rect.center)
self.shoot_delay = pygame.time.get_ticks()
self.energy -= 20
if keys[pygame.K_t] and not self.tread_active and pygame.time.get_ticks() - self.tread_timer > 15000 and self.energy >= 50:
self.tread_active = True
self.tread_timer = pygame.time.get_ticks()
self.energy -= 50
## if pygame.time.get_ticks() - self.energy_timer > 1000:
## self.energy = min(self.energy + 5, 100)
## self.energy_timer = pygame.time.get_ticks()
def shoot(self):
if self.mode == 2:
return [Bullet(self.rect.centerx - 10, self.rect.top), Bullet(self.rect.centerx + 10, self.rect.top)]
return [Bullet(self.rect.centerx, self.rect.top)]
def draw(self, surface):
surface.blit(self.image, self.rect)
if self.tread_active:
tread_rect = tread_bomber.get_rect(center=(self.rect.centerx, self.rect.centery + 30))
surface.blit(tread_bomber, tread_rect)
if pygame.time.get_ticks() - self.tread_timer > 5000:
self.tread_active = False
return Napalm(self.rect.centerx, self.rect.top)
return None
class Enemy:
def __init__(self):
self.frames = invid_frames
self.frame_index = 0
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect(topleft=(random.randint(0, 800 - 30), -50))
self.speed = 3
self.move_timer = pygame.time.get_ticks()
self.direction = random.choice([-1, 1])
self.frame_timer = pygame.time.get_ticks()
def move(self):
self.rect.y += self.speed
if pygame.time.get_ticks() - self.move_timer > 1000:
self.rect.x += self.direction * 2
if self.rect.x < 0:
self.rect.x = 0
self.direction = 1
elif self.rect.x > 800 - self.rect.width:
self.rect.x = 800 - self.rect.width
self.direction = -1
self.move_timer = pygame.time.get_ticks()
if pygame.time.get_ticks() - self.frame_timer > 200:
self.frame_index = (self.frame_index + 1) % len(self.frames)
self.image = self.frames[self.frame_index]
self.frame_timer = pygame.time.get_ticks()
if self.rect.y > 600:
self.rect.y = -50
self.rect.x = random.randint(0, 800 - 30)
def draw(self, surface):
surface.blit(self.image, self.rect)
class Bullet:
def __init__(self, x, y):
self.rect = pygame.Rect(x - 2, y, 5, 10)
self.speed = -15
def move(self):
self.rect.y += self.speed
if self.rect.y < 0:
return False
return True
def draw(self, surface):
pygame.draw.rect(surface, (255, 0, 0), self.rect)
class Napalm:
def __init__(self, x, y):
self.image = napalm_img
self.rect = self.image.get_rect(center=(x, y))
self.speed = -10
self.damage = 5
def move(self):
self.rect.y += self.speed
if self.rect.y < 0:
return False
return True
def draw(self, surface):
surface.blit(self.image, self.rect)
game_over = False
# Game setup
legioss = Legioss()
enemies = [Enemy() for _ in range(5)]
bullets = []
napalms = []
bg_y = 0
bg_speed = 3
score = 0
font = pygame.font.Font(None, 36)
# Main loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_f:
bullets.extend(legioss.shoot())
# Update
if not game_over:
bg_y = (bg_y + bg_speed) % 1200
legioss.move()
napalm = legioss.draw(screen)
if napalm:
napalms.append(napalm)
for enemy in enemies:
enemy.move()
bullets = [bullet for bullet in bullets if bullet.move()]
napalms = [napalm for napalm in napalms if napalm.move()]
for bullet in bullets[:]:
for enemy in enemies[:]:
if bullet.rect.colliderect(enemy.rect):
bullets.remove(bullet)
enemies.remove(enemy)
enemies.append(Enemy())
score += 10
break
for napalm in napalms[:]:
for enemy in enemies[:]:
if napalm.rect.colliderect(enemy.rect):
enemies.remove(enemy)
enemies.append(Enemy())
score += 50
break
if pygame.time.get_ticks() - legioss.collision_timer > 500:
for enemy in enemies:
if enemy.rect.colliderect(legioss.rect):
legioss.energy = max(0, legioss.energy - 10)
legioss.collision_timer = pygame.time.get_ticks()
break
if legioss.energy <= 0:
game_over = True
pygame.mixer.music.stop()
if game_over:
game_over_bg = pygame.Surface((600, 200), pygame.SRCALPHA)
game_over_bg.fill((0, 0, 0, 220)) # Más opaco y grande
screen.blit(game_over_bg, (100, 75)) # Centrado horizontalmente
game_over_font = pygame.font.SysFont('consolas', 64)
game_over_text = game_over_font.render("Game Over", True, WHITE)
screen.blit(game_over_text, (250, 125)) # Centrado en el rectángulo
pygame.display.update()
#bg_y = (bg_y + bg_speed) % 1200
screen.blit(background_img, (0, bg_y - 1200))
screen.blit(background_img, (0, bg_y))
fade = pygame.Surface((800, 20), pygame.SRCALPHA)
for y in range(20):
alpha = int(50 * (y / 20)) # Max alpha 50
pygame.draw.line(fade, (0, 0, 0, alpha), (0, y), (800, y))
screen.blit(fade, (0, 0))
flipped_fade = pygame.transform.flip(fade, False, True)
screen.blit(flipped_fade, (0, 580))
# Draw
for enemy in enemies:
enemy.draw(screen)
for bullet in bullets:
bullet.draw(screen)
for napalm in napalms:
napalm.draw(screen)
legioss.draw(screen)
score_text = font.render(f"Score: {score}", True, WHITE)
energy_text = font.render(f"Energy: {legioss.energy}", True, WHITE)
screen.blit(score_text, (10, 10))
screen.blit(energy_text, (10, 50))
pygame.display.flip()
clock.tick(60)
pygame.quit()
#Musicaafter thenapalm_imgsteps and before the#Classesdefinition steps? My immediate guess is that it is being drawn, but then is being drawn on top of, but unsure if that is something you have looked into earlier or not. \$\endgroup\$