Video games are meant to immerse the player into a sort of virtual reality. We do this mainly visually, but it can make a massive difference and be a massive improvement to your game if you add sounds as well.
Sounds generally come in two major forms: Either "ambient" noise or as results of player actions. With PyGame, you get two choices: Music or Sounds. Music will just play in the background when you call it to, and sounds will play at any time you call them to play. We're going to cover both here by adding them both to our current game. First, we will use a simple tune from YouTube as our game's music and then we'll add a "crash" sound that we will play if we hit any of the blocks.
To start, let's make a sound:
crash_sound = pygame.mixer.Sound("crash.wav")
The above will assign the crash.wav sound file to play when we call crash_sound within PyGame's sound playing functionality. Notice the file is .wav. PyGame can handle .mp3 as well, but it is somewhat glitchy, and will work sometimes and other times it wont. For the safest bet, go with .wav.
Now that we know how to call sounds, how can we do music?
pygame.mixer.music.load('jazz.wav') pygame.mixer.music.play(-1)
The above code will play the music file indefinitely (though you can call it to stop). The -1 signals PyGame to just play forever, but, if you put, say, a 5 in there, then the music would play once and 5 more times.
Now, we want the music to play, and it is, then we need the crash sound to play when crashed. Also, we'd like to stop the music if this is the case.
So, within our crash function...
def crash(): #################################### pygame.mixer.Sound.play(crash_sound) pygame.mixer.music.stop() #################################### largeText = pygame.font.SysFont("comicsansms",115) TextSurf, TextRect = text_objects("You Crashed", largeText)
Above, we're calling PyGame to play the crash_sound, as well as to stop the music. This means the music will start over again if the game is re-played.
Now, the only other thing we may want to do is learn how to pause/unpause music when the player pauses the game. This is easy enough.
In our paused function:
def paused(): ############ pygame.mixer.music.pause() #############
And then of course we must unpause it:
def unpause(): global pause ################# pygame.mixer.music.unpause() ################# pause = False
Full PyGame code:
import pygame import time import random pygame.init() ############# crash_sound = pygame.mixer.Sound("crash.wav") ############# display_width = 800 display_height = 600 black = (0,0,0) white = (255,255,255) red = (200,0,0) green = (0,200,0) bright_red = (255,0,0) bright_green = (0,255,0) block_color = (53,115,255) car_width = 73 gameDisplay = pygame.display.set_mode((display_width,display_height)) pygame.display.set_caption('A bit Racey') clock = pygame.time.Clock() carImg = pygame.image.load('racecar.png') gameIcon = pygame.image.load('carIcon.png') pygame.display.set_icon(gameIcon) pause = False #crash = True def things_dodged(count): font = pygame.font.SysFont("comicsansms", 25) text = font.render("Dodged: "+str(count), True, black) gameDisplay.blit(text,(0,0)) def things(thingx, thingy, thingw, thingh, color): pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh]) def car(x,y): gameDisplay.blit(carImg,(x,y)) def text_objects(text, font): textSurface = font.render(text, True, black) return textSurface, textSurface.get_rect() def crash(): #################################### pygame.mixer.Sound.play(crash_sound) pygame.mixer.music.stop() #################################### largeText = pygame.font.SysFont("comicsansms",115) TextSurf, TextRect = text_objects("You Crashed", largeText) TextRect.center = ((display_width/2),(display_height/2)) gameDisplay.blit(TextSurf, TextRect) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() button("Play Again",150,450,100,50,green,bright_green,game_loop) button("Quit",550,450,100,50,red,bright_red,quitgame) pygame.display.update() clock.tick(15) def button(msg,x,y,w,h,ic,ac,action=None): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() if x+w > mouse[0] > x and y+h > mouse[1] > y: pygame.draw.rect(gameDisplay, ac,(x,y,w,h)) if click[0] == 1 and action != None: action() else: pygame.draw.rect(gameDisplay, ic,(x,y,w,h)) smallText = pygame.font.SysFont("comicsansms",20) textSurf, textRect = text_objects(msg, smallText) textRect.center = ( (x+(w/2)), (y+(h/2)) ) gameDisplay.blit(textSurf, textRect) def quitgame(): pygame.quit() quit() def unpause(): global pause pygame.mixer.music.unpause() pause = False def paused(): ############ pygame.mixer.music.pause() ############# largeText = pygame.font.SysFont("comicsansms",115) TextSurf, TextRect = text_objects("Paused", largeText) TextRect.center = ((display_width/2),(display_height/2)) gameDisplay.blit(TextSurf, TextRect) while pause: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() button("Continue",150,450,100,50,green,bright_green,unpause) button("Quit",550,450,100,50,red,bright_red,quitgame) pygame.display.update() clock.tick(15) def game_intro(): intro = True while intro: for event in pygame.event.get(): #print(event) if event.type == pygame.QUIT: pygame.quit() quit() gameDisplay.fill(white) largeText = pygame.font.SysFont("comicsansms",115) TextSurf, TextRect = text_objects("A bit Racey", largeText) TextRect.center = ((display_width/2),(display_height/2)) gameDisplay.blit(TextSurf, TextRect) button("GO!",150,450,100,50,green,bright_green,game_loop) button("Quit",550,450,100,50,red,bright_red,quitgame) pygame.display.update() clock.tick(15) def game_loop(): global pause ############ pygame.mixer.music.load('jazz.wav') pygame.mixer.music.play(-1) ############ x = (display_width * 0.45) y = (display_height * 0.8) x_change = 0 thing_startx = random.randrange(0, display_width) thing_starty = -600 thing_speed = 4 thing_width = 100 thing_height = 100 thingCount = 1 dodged = 0 gameExit = False while not gameExit: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x_change = -5 if event.key == pygame.K_RIGHT: x_change = 5 if event.key == pygame.K_p: pause = True paused() if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: x_change = 0 x += x_change gameDisplay.fill(white) things(thing_startx, thing_starty, thing_width, thing_height, block_color) thing_starty += thing_speed car(x,y) things_dodged(dodged) if x > display_width - car_width or x < 0: crash() if thing_starty > display_height: thing_starty = 0 - thing_height thing_startx = random.randrange(0,display_width) dodged += 1 thing_speed += 1 thing_width += (dodged * 1.2) if y < thing_starty+thing_height: print('y crossover') if x > thing_startx and x < thing_startx + thing_width or x+car_width > thing_startx and x + car_width < thing_startx+thing_width: print('x crossover') crash() pygame.display.update() clock.tick(60) game_intro() game_loop() pygame.quit() quit()
That is all for the PyGame basics series. You can choose another topic from the
Alternatively, you can check out the PyOpenGL series, which uses OpenGL to create 3D renderings using PyGame: