Python游戏编程(十二)SpritsAndSounds

前面我们介绍了如何创建具有图形并且可以接收键盘和鼠标输入的GUI程序。我们还介绍了如何绘制不同的形状。在这个程序中,我们将介绍如何在游戏中显示图像、播放声音和音乐。

目录

(一)循环准备

1)创建窗口和数据结构

添加一个精灵

改变一个精灵的大小

2)创建音乐和声音

添加声音文件

切换和关闭声音

(二)游戏循环

1)把玩家绘制到窗口上

2)检查碰撞


主要内容:

  • 声音文件和图像文件;
  • 绘制精灵(指用作屏幕上图形的一部分的一个单独二维图像。);
  • 添加音乐和声音;
  • 打开或关闭声音;

(一)循环准备

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()

参考:

  1. Python游戏编程快速上手
发布了12 篇原创文章 · 获赞 3 · 访问量 3294

猜你喜欢

转载自blog.csdn.net/weixin_45755966/article/details/104450742
今日推荐