URLhttps://learnscript.net/zh-hant/pygame/sprite/animation/
    複製連結移至說明  範例

    如何通過精靈表單實作動畫

    閱讀 3:32·字數 1063·發佈 
    Youtube 頻道
    訂閱 375

    前言

    因為 Pygame 沒有直接提供與精靈動畫相關的內建類別,因此,需要開發人員自行編寫程式碼實作動畫效果。本文將根據影像檔案的儲存方式,介紹兩種常見的動畫實作方式。

    方式一:載入多個影像檔案實作動畫

    載入多個影像檔案是一種相對簡單的動畫實作方式,每一個影像檔案可對應動畫中的一個影格。這一般需要呼叫image模組的load函式,所產生的Surface物件會指派給精靈物件的image變數。

    當然,嚴格意義上來說,下面的範例所實作的並不像動畫,更像是狀態的切換。

    # 載入門開關狀態的影像
    img_closed = pygame.image.load('doors_leaf_closed.png').convert_alpha()
    img_open = pygame.image.load('doors_leaf_open.png').convert_alpha()
    
    class Door(pygame.sprite.Sprite): def __init__(self, *groups): super().__init__(*groups) self.image = img_closed # 初始狀態為關閉 self.rect = self.image.get_rect()
    def update(self, keys): if keys[pygame.K_SPACE]: self.image = img_open # 按下空格鍵顯示開門狀態 else: self.image = img_closed # 釋放空格鍵顯示關門狀態

    方式二:通過精靈表單實作動畫

    精靈表單一般包含了動畫中的所有影格,因此,要完成一個動畫只需要載入一個影像檔案。這同樣需要呼叫image模組的load函式,並呼叫所傳回的Surface物件的subsurface方法,以獲得多個子表面,每個子表面對應了精靈表單中的一個影格。之後,可在遊戲迴圈或精靈的update方法中,將不同的子表面指派給精靈物件的image變數。

    subsurface方法有三種形式,本文使用的是四個浮點數參數的一種,前兩個浮點數確定子表面左上角在父表面中的座標,後兩個浮點數指定子表面的寬度和高度。

    subsurface 方法傳回的子表面

    subsurface方法傳回的子表面與父表面共用像素資料,不會建立新的像素。你不需要對子表面呼叫convert_alpha方法,因為,如何繪製像素通常取決於父表面。

    在下面的範例中,由於沒有控製子表面的切換速度,因此,寶箱的播放速度可能會很快。

    # 載入精靈表單
    sprite_sheet = pygame.image.load('chest_001.png').convert_alpha()
    
    # 建立子表面串列 img_cs = [sprite_sheet.subsurface(pygame.Rect(i*16, 0, 16, 32)) for i in range(6)]
    class Chest(pygame.sprite.Sprite): def __init__(self, *groups): super().__init__(*groups) self.image_index = 0 # 目前影格索引 self.image = img_cs[self.image_index] self.rect = self.image.get_rect()
    def update(self): self.image_index = (self.image_index + 1) % len(img_cs) # 迴圈播放 self.image = img_cs[self.image_index]

    控製動畫播放速度

    如果遊戲的影格率為60,那麽上面例子中的寶箱動畫,每秒可播放10次。為了降低動畫的播放速度,可新增一些變數進行控製。

    下面,為Chest新增類別變數WAIT和變數wait,用於控製子表面的切換時間間隔,在update方法判斷是否可以進行子表面的切換。

    調整WAIT的值可改變動畫播放速度。

    class Chest(pygame.sprite.Sprite):
    	WAIT = 5 # 每 5 影格切換一次動畫影格
    
    def __init__(self, *groups): super().__init__(*groups) self.wait = 0 # 影格計數器 # …
    def update(self): self.wait += 1 if self.wait >= self.WAIT: self.wait = 0 self.image_index = (self.image_index + 1) % len(img_cs) # 迴圈播放 self.image = img_cs[self.image_index]

    講解影片

    Pygame 使用精靈表單實作 Sprite 精靈動畫,以及控製動畫播放速度·YouTube