Sounds and Held Keys
Part of the Sound and Game Feel section of Coddy's Pygame journey. Lesson 4 of 23.
Hold Space and the ship fires a laser every 12 frames. The starter plays the laser sound like this:
if keys[pygame.K_SPACE]:
laser_sound.play()
if cooldown == 0:
lasers.append(...)keys[pygame.K_SPACE] is true on every frame the key is down. So while you hold Space, the sound starts 60 times a second, although only 5 lasers fly. You hear a rough buzz instead of shots.
The fix is the same rule as before: play the sound where the thing happens. A shot happens inside if cooldown == 0:, so the sound goes there:
if keys[pygame.K_SPACE]:
if cooldown == 0:
lasers.append(...)
laser_sound.play()Now every laser has its sound and nothing else does. For an action that happens once per press, such as a jump, play the sound in the KEYDOWN event instead: there is one event per press, however long the key stays down.
Challenge
EasyHold Space and the ship fires a laser every 12 frames, but the sound buzzes. Move laser_sound.play() so it plays once for each laser fired: into the if cooldown == 0: branch, after the laser is added.
Try it yourself
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Lasers")
clock = pygame.time.Clock()
laser_sound = pygame.mixer.Sound("assets/sounds/laser.ogg")
laser_sound.set_volume(0.5)
ship = pygame.Rect(220, 300, 40, 30)
lasers = []
cooldown = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
ship.x -= 5
if keys[pygame.K_RIGHT]:
ship.x += 5
ship.clamp_ip(screen.get_rect())
if cooldown > 0:
cooldown -= 1
if keys[pygame.K_SPACE]:
laser_sound.play()
if cooldown == 0:
lasers.append(pygame.Rect(ship.centerx - 2, ship.top - 12, 4, 12))
cooldown = 12
for laser in lasers:
laser.y -= 8
lasers = [laser for laser in lasers if laser.bottom > 0]
screen.fill((30, 30, 46))
for laser in lasers:
pygame.draw.rect(screen, (255, 230, 90), laser)
pygame.draw.rect(screen, (80, 200, 230), ship)
pygame.display.flip()
clock.tick(60)
pygame.quit()
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Sound and Game Feel
Practice on your own: Pygame playground