Python遊戲編程(十)Animation

我們將編寫一個程序來實現積木在窗口中彈跳的效果。這些積木具有不同的顏色和大小,並且只在對角線上移動。爲了讓積木有動畫的效果,我們將在遊戲循環的每一次迭代中,讓這些積木移動一些像素。這就會使得積木看上去像是在屏幕上移動。

目錄

(一)遊戲說明

(二)代碼分析

1)設置常量變量

2)用於方向、速度、顏色的常量變量

3)設置積木 數據結構

4)遊戲循環

1.處理玩家退出的情況

2.移動、彈跳積木

3.繪製窗口


(一)遊戲說明

這個程序稱不上是一個遊戲,只是通過一些細微的改變實現一個積木的移動。程序中的積木就是用pygame.draw.rect()函數繪製的矩形。在這個程序中,我們有三個不同顏色的積木來回移動,並且從窗口的牆壁彈回。每個積木將在4條對角線方向中的一條上移動。當積木碰到了窗口,它就會從邊緣上彈回來,並在一條新的對角線上移動。

所謂積木的移動,就是快速的繪製一個新的矩形,只不過是速度很快,我們看起來就像是在移動一樣。

 

(二)代碼分析

1)設置常量變量

import pygame, sys, time
from pygame.locals import *

# Set up pygame.
pygame.init()

# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

首先是導入模塊,然後對pygame模塊進行初始化。

這裏我們將使用常量變量,以便我們想要修改窗口大小的時候,只需要修改WINDOWWIDTH和WINDOWHEIGHT即可。當然,如果窗口的寬度和高度從不改變,那麼使用常量也可。

2)用於方向、速度、顏色的常量變量

# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'

MOVESPEED = 4

# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

對於方向,我們也可以不使用常量,而是將這些方向常量賦值給變量,使用這些變量表示。兩者的區別是:

  • 如果直接使用字符串“downlwft”表示左下對角線方向,當字符串輸入錯誤的時候,最終會得到一個bug,將會導致程序行爲異常,即便程序還不會崩潰。
  • 如果使用變量,當不小心輸入了錯誤的變量名,Python就會報錯導致程序崩潰。這仍然很糟糕,但是我們將立刻發現它並且修改它。

對於速度,我們定義了MOVESPEED = 4常量變量,這告訴程序,在遊戲循環的每一次迭代中,每個積木應該移動多少個像素。

對於顏色,pygame使用3個整數值的一個元組,來表示紅色、綠色和藍色數量的RGB值。整數值從0到255.

 

使用常量是爲了有更好的可讀性。

 

3)設置積木 數據結構

# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]

這裏使用字典來表示三個積木,並且將這三個積木放到boxes列表中,這樣輸入boxes[0]就可以訪問b1中的字典數據結構,輸入boxes[0]['color']就可以訪問b1中的‘color’鍵的值。

 

4)遊戲循環

遊戲循環負責實現移動積木的動畫。

動畫是這樣實現的:繪製一系列略微不同的圖像,這些圖像一個接着一個地顯示。在我們的動畫中,圖像都是移動的積木,略微不同的是每一個積木的位置。在每一個圖像中,積木都會移動4個像素。圖像顯示得如此之快,以至於積木看上去就像是在屏幕上平滑地移動。如果一個積木碰到了窗口的邊緣,遊戲循環將會通過改變該積木的方向而令其彈回。

1.處理玩家退出的情況

當玩家通過關閉窗口而退出的時候,我們需要停止遊戲。我們需要在遊戲循環中做到這一點,以便程序持續地檢查受否有一個QUIT事件。

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

爲了使窗口出現運動軌跡,需要在每一次圖形改變之後清楚整個窗口:

    # Draw the white background onto the surface.
    windowSurface.fill(WHITE)

 

2.移動、彈跳積木

    for b in boxes:
        # Move the box data structure.
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

        # Check whether the box has moved out of the window.
        if b['rect'].top < 0:
            # The box has moved past the top.
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
                
        if b['rect'].bottom > WINDOWHEIGHT:
            # The box has moved past the bottom.
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
            # The box has moved past the left side.
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
            # The box has moved past the right side.
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT

3.繪製窗口

        # Draw the box onto the surface.
        pygame.draw.rect(windowSurface, b['color'], b['rect'])

    # Draw the window onto the screen.
    pygame.display.update()
    time.sleep(0.02)

 

 

源代碼:

import pygame, sys, time
from pygame.locals import *

# Set up pygame.
pygame.init()

# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'

MOVESPEED = 4

# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]

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

    # Draw the white background onto the surface.
    windowSurface.fill(WHITE)
    for b in boxes:
        # Move the box data structure.
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

        # Check whether the box has moved out of the window.
        if b['rect'].top < 0:
            # The box has moved past the top.
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
                
        if b['rect'].bottom > WINDOWHEIGHT:
            # The box has moved past the bottom.
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
            # The box has moved past the left side.
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
            # The box has moved past the right side.
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT

        # Draw the box onto the surface.
        pygame.draw.rect(windowSurface, b['color'], b['rect'])

    # Draw the window onto the screen.
    pygame.display.update()
    time.sleep(0.02)

 

 

 

參考:

  1. Python遊戲編程快速上手

 

 

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