使用pygame.surface.subsurface() 來實現精靈動畫

前兩天寫了一個使用blit  實現動畫的文章.今天我們我們用 另一個方法surface來實現精靈動畫.這兩個方法本質上的區別在於.  blit()   是直接把圖像繪製在surface表面.而subsurface()是先將圖像提取子表面.然後通過Sprite.draw, 或者Group.draw將自表面繪製出來.

在使用的時候主要還是看個人習慣.對於我來說一般在寫一些只做單詞循環的動畫,比如飛機爆炸產生的火花,我就用blit(),如果是需要不斷循環的動畫,比如英雄的動作.我喜歡用sub

關於surface.subfurface()方法的工作原理,我這裏有一張簡單的圖來說明. 

在這裏要注意的是,要使用子表面實現動畫時,類中要有兩個rect參數,第一個是self.rect這個rect參數是實例的rect屬性,在使用sprite.draw(),或者group.draw()的時候,作爲位置參數傳遞給方法.第二個rect參數是框架參數,也就是你要提取的一個子表面的大小.在公式中,我們用

self.frame_rect.x = (self.frame % 4) * self.frame_rect.width
self.frame_rect.y = (self.frame // 4) * self.frame_rect.height

來計算子表面框架在剪切時所處的位置.

對了這裏有一個地方要說明一下.subsurface()這個方法在提取子表面的時候,默認的topleft是0,0.  也就是說,如果你想讓動畫繪製在屏幕某一個座標的時候.記得要在frame_rect(子表面框架)變量聲明瞭以後再去更改self.rect的座標值.

完整的代碼如下,這次用的是一個在網上找的爆炸火花.

完整的代碼如下:

#coding = utf-8

import pygame,sys
from pygame.sprite import Sprite
from pygame.sprite import Group

class Mysprite(Sprite):
	def __init__(self):
		super().__init__()
		self.mast_image = pygame.image.load('2233.jpg') #讀取圖像
		self.rect = self.mast_image.get_rect() #獲取圖像矩形參數
		self.frame_rect = self.rect.copy() #聲明框架參數
		self.rect.x,self.rect.y = 400,300  #這裏是我實驗的動畫座標繪製,如果把這兩個參數放在第12行之前,那麼就會報錯,顯示子表面繪製超出了範圍 .
		self.frame_rect.width /= 4
		self.frame_rect.height /= 4
		self.frame = 0
		self.last_frame = (self.rect.width // self.frame_rect.width) * (self.rect.height // self.frame_rect.height) - 1
		self.old_frame = 1
		self.last_time = 0

	def update(self):
		self.current_time = pygame.time.get_ticks()
		rate = 100 #因爲這個屬性在別的地方不會有調用,所以這裏我就寫成了方法的局部變量
		if self.current_time >= self.last_time + rate:
			self.frame += 1
			if self.frame > self.last_frame:
				self.frame = 0
			self.last_time = self.current_time

		if self.old_frame != self.frame:
			self.frame_rect.x = (self.frame % 4) * self.frame_rect.width
			self.frame_rect.y = (self.frame // 4) * self.frame_rect.height
			self.old_frame = self.frame

		self.image = self.mast_image.subsurface(self.frame_rect) #這裏就是在生成子表面

pygame.init()
screen = pygame.display.set_mode((800,600))
color = (255,255,255)
mysprite = Mysprite()
group = Group()
group.add(mysprite)
tick = pygame.time.Clock()

while True:
	tick.tick(60)
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit()

	screen.fill(color)
	group.update()
	group.draw(screen)
	pygame.display.update()

 

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