使用pygame.surface.subsurface() 来实现精灵动画

前两天写了一个使用blit  实现动画的文章.今天我们我们用 另一个方法surface来实现精灵动画.这两个方法本质上的区别在于.  blit()   是直接把图像绘制在surface表面.而subsurface()是先将图像提取子表面.然后通过Sprite.draw, 或者Group.draw将自表面绘制出来.

在使用的时候主要还是看个人习惯.对于我来说一般在写一些只做单词循环的动画,比如飞机爆炸产生的火花,我就用blit(),如果是需要不断循环的动画,比如英雄的动作.我喜欢用sub

关于surface.subfurface()方法的工作原理,我这里有一张简单的图来说明. 使用pygame.surface.subsurface() 来实现精灵动画_第1张图片

在这里要注意的是,要使用子表面实现动画时,类中要有两个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的坐标值.

完整的代码如下,这次用的是一个在网上找的爆炸火花.

使用pygame.surface.subsurface() 来实现精灵动画_第2张图片

完整的代码如下:

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

 

你可能感兴趣的:(pygame,python)