本系列博客介绍以python+pygame库进行小游戏的开发。有写的不对之处还望各位海涵。

直到现在我们已经学了很多pygame基础知识了,从这篇博客开始我们将会学习pygame中高级部分,更多和精灵模块,冲突检测相关的知识。

一、Sprite模块、sprite对象

在pygame.sprite模块里面包含了一个名为Sprite类,他是pygame本身自带的一个精灵。但是这个类的功能比较少,因此我们新建一个类对其继承,在sprite类的基础上丰富,以方便我们的使用。

首先来了解一下如何使用sprite类来加载动画吧。

1、精灵序列图

将要加载的动画帧放在一个精灵序列图里面,然后在程序里面调用它。pygame会自动更新动画帧,这样一个动态的图像就会展现在我们面前了。

下面是一个典型的精灵序列图:行和列的索引都是从0开始的。

2、加载精灵图序列:

在加载一个精灵图序列的时候,我们需要告知程序一帧的大小,(传入帧的宽度和高度,文件名)。

除此之外,还需要告诉精灵类,精灵序列图里面有多少列。load函数可以加载一个精灵序列图。

def load(self, filename, width, height, columns):
self.master_image = pygame.image.load(filename).convert_alpha()
self.frame_width = width
self.frame_height = height
self.rect = 0,0,width,height
self.columns = columns

3.更新帧

一个循环动画通常是这样工作的:从第一帧不断的加载直到最后一帧,然后在折返回第一帧,并不断重复这个操作。

self.frame += 1
if self.frame > self.last_frame:
self.frame = self.first_frame
self.last_time = current_time

但是如果只是这样做的话,程序会一股脑地将动画播放完了,我们想让它根据时间间隔一张一张的播放,因此加入定时的代码。

pygame中的time模块有一个get_ticks()方法可以满足定时的需要。

ticks = pygame.time.get_ticks()

然后将ticks变量传递给sprite的update函数,这样就可以轻松让动画按照帧速率来播放了。哦,帧速率还没有设置,咱们现在设置一下帧速率。

启动一个定时器,然后调用tick(num)函数就可以让游戏以num帧来运行了。

framerate = pygame.time.Clock()
framerate.tick(60)

4、绘制帧

sprite.draw()方法是用来绘制帧的,但是这个函数是由精灵来自动调用的,我们没有办法重写它,因此需要在update函数里面做一些工作。

首先需要计算单个帧左上角的x,y位置值(x表示列编号,y表示行编号):

frame_x = (self.frame % self.columns) * self.frame_width
#用帧数目除以行数,然后在乘上帧的高度
frame_y = (self.frame // self.columns) * self.frame_height

然后将计算好的x,y值传递给位置rect属性。

frame_x = (self.frame % self.columns) * self.frame_width
frame_y = (self.frame // self.columns) * self.frame_height
rect = ( frame_x, frame_y, self.frame_width, self.frame_height )
self.image = self.master_image.subsurface(rect)

5、精灵组

当程序中有大量的实体的时候,操作这些实体将会是一件相当麻烦的事,那么有没有什么容器可以将这些精灵放在一起统一管理呢?答案就是精灵组。

pygame使用精灵组来管理精灵的绘制和更新,精灵组是一个简单的容器。

使用pygame.sprite.Group()函数可以创建一个精灵组:

group = pygame.sprite.Group()
group.add(sprite_one)

精灵组也有update和draw函数:

group.update()
group.draw()

二、自定义的精灵类

好了,通过前面的学习,我们已经了解了一些精灵的知识了,现在我们将前面说到的方法封装成一个自定义的类,以方便我们的调用,这个类继承自pygame.sprite.Sprite:

 class MySprite(pygame.sprite.Sprite):
def __init__(self, target):
pygame.sprite.Sprite.__init__(self) #基类的init方法
self.target_surface = target
self.image = None
self.master_image = None
self.rect = None
self.topleft = 0,0
self.frame = 0
self.old_frame = -1
self.frame_width = 1
self.frame_height = 1
self.first_frame = 0
self.last_frame = 0
self.columns = 1
self.last_time = 0 def load(self, filename, width, height, columns):
self.master_image = pygame.image.load(filename).convert_alpha()
self.frame_width = width
self.frame_height = height
self.rect = 0,0,width,height
self.columns = columns
rect = self.master_image.get_rect()
self.last_frame = (rect.width // width) * (rect.height // height) - 1 def update(self, current_time, rate=60):
#更新动画帧
if current_time > self.last_time + rate:
self.frame += 1
if self.frame > self.last_frame:
self.frame = self.first_frame
self.last_time = current_time if self.frame != self.old_frame:
frame_x = (self.frame % self.columns) * self.frame_width
frame_y = (self.frame // self.columns) * self.frame_height
rect = ( frame_x, frame_y, self.frame_width, self.frame_height )
self.image = self.master_image.subsurface(rect)
self.old_frame = self.frame

好了现在我们写一个小程序来测试一下这个类的性能怎么样。

这里我用ps制作了一个简单的精灵序列图,咱们就用这个萌萌的嗷大喵好了:

代码:

import pygame
from pygame.locals import * class MySprite(pygame.sprite.Sprite):
def __init__(self, target):
pygame.sprite.Sprite.__init__(self)
self.target_surface = target
self.image = None
self.master_image = None
self.rect = None
self.topleft = 0,0
self.frame = 0
self.old_frame = -1
self.frame_width = 1
self.frame_height = 1
self.first_frame = 0
self.last_frame = 0
self.columns = 1
self.last_time = 0 def load(self, filename, width, height, columns):
self.master_image = pygame.image.load(filename).convert_alpha()
self.frame_width = width
self.frame_height = height
self.rect = 0,0,width,height
self.columns = columns
rect = self.master_image.get_rect()
self.last_frame = (rect.width // width) * (rect.height // height) - 1 def update(self, current_time, rate=60):
if current_time > self.last_time + rate:
self.frame += 1
if self.frame > self.last_frame:
self.frame = self.first_frame
self.last_time = current_time if self.frame != self.old_frame:
frame_x = (self.frame % self.columns) * self.frame_width
frame_y = (self.frame // self.columns) * self.frame_height
rect = ( frame_x, frame_y, self.frame_width, self.frame_height )
self.image = self.master_image.subsurface(rect)
self.old_frame = self.frame pygame.init()
screen = pygame.display.set_mode((800,600),0,32)
pygame.display.set_caption("精灵类测试")
font = pygame.font.Font(None, 18)
framerate = pygame.time.Clock() cat = MySprite(screen)
cat.load("sprite.png", 100, 100, 4)
group = pygame.sprite.Group()
group.add(cat) while True:
framerate.tick(30)
ticks = pygame.time.get_ticks() for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
key = pygame.key.get_pressed()
if key[pygame.K_ESCAPE]:
exit() screen.fill((0,0,100)) group.update(ticks)
group.draw(screen)
pygame.display.update()

效果图:萌萌的嗷大喵跃然于屏幕上。看起来功能还不错的说。

大家也可以制作一些自己喜欢的精灵序列图,然后加载并查看他们的效果。

关于精灵与精灵之间的冲突检测,精灵与组之间的碰撞检测,我们将会放在下个博客一起学习。

最新文章

  1. Apache Server 添加虚拟主机(Virtual Host )
  2. LSM树由来、设计思想以及应用到HBase的索引
  3. express创建项目
  4. python剑指网络
  5. Nginx环境下配置PHP使用的SSL认证(https)
  6. 小A老空调需求管理小记
  7. java多线程编程(1) 线程的基本知识
  8. Find命令简介
  9. input 图片上传,第二次上传同一张图片失效
  10. git 安装部署教程
  11. mysql5.7.20完全卸载 win10
  12. 2016 Multi-University Training Contest 2题解报告
  13. msgs no .h file
  14. python3 中对arrow库的总结(转发)
  15. 23种设计模式之桥接模式(Bridge)
  16. React Native 的组件之底部导航栏 TabBarIOS(一)
  17. Android开发之漫漫长途 Ⅲ——Activity的显示之Window和View(2)
  18. 求二维数组最大子数组的和。郭林林&胡潇丹
  19. Python模块Pygame安装
  20. 不改源代码,修改服务器配置,解决全局Get中文乱码问题

热门文章

  1. Velocity笔记
  2. jQuery中读取json文件示例代码
  3. 20145206实验四《Android开发基础》
  4. linux文件描述符open file descriptors与open files的区别
  5. SQLServer内置函数
  6. 【数据库】 防止sql注入,过滤敏感关键字
  7. 10g 11g配置Logical Standby
  8. 判断一个类到底是从哪个jar包中调用的工具类
  9. MS SQL数据批量备份还原(适用于MS SQL 2005+) 分类: SQL Server 数据库 2015-03-10 14:32 103人阅读 评论(0) 收藏
  10. 百度编辑器UEditor ASP.NET示例Demo 分类: ASP.NET 2015-01-12 11:18 346人阅读 评论(0) 收藏