前面我们介绍了如何创建具有图形并且可以接收键盘和鼠标输入的GUI程序。我们还介绍了如何绘制不同的形状。在这个程序中,我们将介绍如何在游戏中显示图像、播放声音和音乐。
目录
主要内容:
- 声音文件和图像文件;
- 绘制精灵(指用作屏幕上图形的一部分的一个单独二维图像。);
- 添加音乐和声音;
- 打开或关闭声音;
(一)循环准备
import pygame, sys, time, random
from pygame.locals import *
# Set up pygame.
pygame.init()
mainClock = pygame.time.Clock()
# Set up the window.
WINDOWWIDTH = 800
WINDOWHEIGHT = 800
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT),0, 32)
pygame.display.set_caption('Sprites and Sounds')
# Set up the colors.
WHITE = (255, 255, 255)
# Set up the block data structure.
player = pygame.Rect(300, 100, 40, 40)
playerImage = pygame.image.load('player.png')
playerStretchedImage = pygame.transform.scale(playerImage, (40, 40))
foodImage = pygame.image.load('cherry.png')
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20),
random.randint(0, WINDOWHEIGHT - 20), 20, 20))
foodCounter = 0
NEWFOOD = 40
# Set up keyboard variables.
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 6
# Set up the music.
pickUpSound = pygame.mixer.Sound('pickup.wav')
pygame.mixer.music.load('bg.mp3')
pygame.mixer.music.play(-1, 0.0)
musicPlaying = True
1)创建窗口和数据结构
程序中的大部分代码和Collision Detection程序相同。我们只介绍精灵和声音部分。
添加一个精灵
# Set up the block data structure.
player = pygame.Rect(300, 100, 40, 40)
playerImage = pygame.image.load('player.png')
playerStretchedImage = pygame.transform.scale(playerImage, (40, 40))
foodImage = pygame.image.load('cherry.png')
player变量将存储一个Rect对象,该对象记录玩家的位置以及玩家的大小。player变量没有包含玩家的图像,只有玩家的位置和大小。在程序开始处,玩家左上角位于坐标(300,100)处,一开始玩家有40个像素高和40个像素宽。
pygame.image.load()接收了一个字符串参数,这是要加载的图像的文件名。返回一个Surface对象,把文件中的图像绘制到了该对象上。我们把这个Surface对象保存到playerImage中。
改变一个精灵的大小
playerStretchedImage = pygame.transform.scale(playerImage, (40, 40))
这里我们使用了pygame.transform模块中的一个新的函数。pygame.transform.scale()函数可以缩小和放大一个精灵。第一个参数表示在其上绘制了图像的pygame.Surface对象。第二个参数是一个元组,表示第1个参数中的图像的新的宽度和高度。
pygame.transform.scale()函数返回了一个pygame.Surface对象,图像以新的大小绘制于其上。我们在playerImage变量中保存了初始图像,而在playerStretcheImage变量中保存了缩放后的图像。
记住,我们的图像文件,要保存在和代码文件相同的目录下,不然pygame会报错。
2)创建音乐和声音
在pygame中有两个声音模块。
- pygame.mixer模块:可以在游戏中播放简短音效;
- pygame.mixer.music模块:可以播放背景音乐。
添加声音文件
# Set up the music.
pickUpSound = pygame.mixer.Sound('pickup.wav')
pygame.mixer.music.load('bg.mp3')
pygame.mixer.music.play(-1, 0.0)
musicPlaying = True
调用pygame.mixer.Sound()构造函数来创建一个pygame.mixer.Sound对象(简称Sound对象)。这个对象有一个play()方法,调用该方法可以播放音效。
pygame.mixer.music.load('bg.mp3')开始加载背景音乐。
pygame.mixer.music.play(-1, 0.0)函数开始播放音乐。
- 第一个参数告诉pygame第一次播放背景音乐之后还要再播放几次背景音乐。所以设置为5则导师pygame播放6次。这里设置为-1,表示循环播放。
- 第二个参数是开始播放声音文件的位置,传入0.0将从头开始播放背景音乐。如果是2.5则将从音乐开头的2.5秒处开始播放背景音乐。
musicPlaying = True变量将有一个Boolean值,告诉程序是否应该播放背景音乐和音效。
切换和关闭声音
我们可以调用pygame.mixer.music.stop()来停止音乐。
if event.key == K_m:
if musicPlaying:
pygame.mixer.music.stop()
else:
pygame.mixer.music.play(-1, 0.0)
musicPlaying = not musicPlaying
M键将打开和关闭背景音乐。
(二)游戏循环
# Run the game loop.
while True:
# Check for the QUIT event.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
# Change the keyboard variables.
if event.key == K_LEFT or event.key == K_a:
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == K_d:
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == K_w:
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == K_s:
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == K_a:
moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
moveRight = False
if event.key == K_UP or event.key == K_w:
moveUp = False
if event.key == K_DOWN or event.key == K_s:
moveDown = False
if event.key == K_x:
player.top = random.randint(0, WINDOWHEIGHT -
player.height)
player.left = random.randint(0, WINDOWWIDTH -
player.width)
if event.key == K_m:
if musicPlaying:
pygame.mixer.music.stop()
else:
pygame.mixer.music.play(-1, 0.0)
musicPlaying = not musicPlaying
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0] - 10,
event.pos[1] - 10, 20, 20))
foodCounter += 1
if foodCounter >= NEWFOOD:
# Add new food.
foodCounter = 0
foods.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20),
random.randint(0, WINDOWHEIGHT - 20), 20, 20))
# Draw the white background onto the surface.
windowSurface.fill(WHITE)
# Move the player.
if moveDown and player.bottom < WINDOWHEIGHT:
player.top += MOVESPEED
if moveUp and player.top > 0:
player.top -= MOVESPEED
if moveLeft and player.left > 0:
player.left -= MOVESPEED
if moveRight and player.right < WINDOWWIDTH:
player.right += MOVESPEED
# Draw the block onto the surface.
windowSurface.blit(playerStretchedImage, player)
# Check whether the block has intersected with any food squares.
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
player = pygame.Rect(player.left, player.top,
player.width + 2, player.height + 2)
playerStretchedImage = pygame.transform.scale(playerImage,
(player.width, player.height))
if musicPlaying:
pickUpSound.play()
# Draw the food.
for food in foods:
windowSurface.blit(foodImage, food)
# Draw the window onto the screen.
pygame.display.update()
mainClock.tick(40)
1)把玩家绘制到窗口上
记住,playerStrectchedImage中存储的值是一个Surface对象。这里使用blit()把玩家的精灵绘制到窗口的Surface对象上(存储在windowSurface中)。
# Draw the block onto the surface.
windowSurface.blit(playerStretchedImage, player)
blit()方法的第2个参数是一个Rect对象,它指定了把精灵渲染到Surface对象上的何处。存储在player中的Rect对象,记录了玩家在窗口中的位置。
2)检查碰撞
这里的碰撞检测和Collision Detection中的差不多,但是加入了一部分增加像素的代码。实现碰撞之后自身增大。就像是吃了食物之后自身长胖了一样。
# Check whether the block has intersected with any food squares.
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
player = pygame.Rect(player.left, player.top,
player.width + 2, player.height + 2)
playerStretchedImage = pygame.transform.scale(playerImage,
(player.width, player.height))
if musicPlaying:
pickUpSound.play()
参考: