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遊戲編程快速上手

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章