上一章介绍了位图编程的相关内容,这一章就开始实现动画操作,那么主要就是要来了解pygame.sprite模块。

在pygame.sprite模块中,有一个名为Sprite的类,我们需要对其进行扩展使其成为一个我们需要的精灵类,pygame精灵以image和rect为基础,因此关键就是围绕这两个属性编写代码。

首先我们使用如下精灵图:


可以看到,精灵序列图包含了由“帧”组成的行和列,其中的每一个都是动画序列的一帧,注意,每一帧都带有行和列的标签,且标签是从0开始的。

精灵组会自动调用update()方法进行帧的变动,也会自动调用draw()方法进行帧的绘画,因此我们只需要对update()方法进行相应的扩展即可,即在update()方法中将Sprite.image和Sprite.rect设置为有效值,则Sprite.draw()方法就会自动进行相应的处理:

    def update(self, current_time, rate=30):# 帧变动if current_time > self.last_time + rate:self.frame += 1if self.frame > self.last_frame:self.frame = self.first_frameself.last_time = current_timeif self.frame != self.old_frame:frame_x = (self.frame % self.columns) * self.frame_widthframe_y = (self.frame // self.columns) * self.frame_heightrect = Rect(frame_x, frame_y, self.frame_width, self.frame_height)# 将要展示的图片送给image属性,以便展示出来self.image = self.master_image.subsurface(rect)self.old_frame = self.frame

其中frame_x和frame_y用于确定应该使用哪个帧,然后调用subsurface()方法,这个方法不会复制或传送图像,而只是设置一个指针指向已有的主图像,以便进行一些轻快的更新。

为了方便同时对多个精灵组进行更新,我们可以将这些精灵放到同一个组中,类似于Linux系统中的用户管理方式,之后只需要对组进行操作,即可实现对多个精灵组进行更新。

group = pygame.sprite.Group()

通过以上方法就可以创建一个组

group.add(dragon)

然后使用如上方法即可将精灵加入到一个组中

之后要实现跳跃功能:

        if player_jumping:player.Y += jump_veljump_vel += 0.5if player.Y > player_start_y:player_jumping = Falseplayer.Y = player_start_yjump_vel = 0.0

如上,当检测到玩家按下空格键之后,jump_vel设置初值为-8.0,之后jump_vel都+=0.5,以保证玩家可以落回地面。

那么最后一个问题就是玩家与箭的碰撞检测,龙与箭的碰撞检测,以及玩家与龙的碰撞检测(即玩家被龙吃掉)的解决:

     # 检测玩家和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, player):reset_arrow()player.X -= 10# 检测龙和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, dragon):reset_arrow()dragon.X -= 10# 检测玩家和龙是否碰撞,即玩家是否会被龙吃了if pygame.sprite.collide_rect(player, dragon):game_over = True

如上,我们使用pygame.sprite.collide_rect()方法来检测两个精灵是否发生了碰撞。

完整源代码:

import random
import sys
import pygame
from pygame.locals import *# 类中的X、Y、position用于设置精灵的位置
class MySprite(pygame.sprite.Sprite):def __init__(self, target):# 调用父类的初始化方法pygame.sprite.Sprite.__init__(self)self.master_image = Noneself.frame = 0self.old_frame = -1self.frame_width = 1self.frame_height = 1self.first_frame = 0self.last_frame = 0self.columns = 1self.last_time = 0def getx(self):return self.rect.xdef setx(self, value):self.rect.x = valueX = property(getx, setx)def gety(self):return self.rect.ydef sety(self, value):self.rect.y = valueY = property(gety, sety)def getpos(self):return self.rect.topleftdef setpos(self, pos):self.rect.topleft = posposition = property(getpos, setpos)def load(self, filename, width, height, columns):self.master_image = pygame.image.load(filename).convert_alpha()self.frame_width = widthself.frame_height = heightself.rect = Rect(0, 0, width, height)self.columns = columnsrect = self.master_image.get_rect()self.last_frame = (rect.width // width) * (rect.height // height) - 1def update(self, current_time, rate=30):# 帧变动if current_time > self.last_time + rate:self.frame += 1if self.frame > self.last_frame:self.frame = self.first_frameself.last_time = current_timeif self.frame != self.old_frame:frame_x = (self.frame % self.columns) * self.frame_widthframe_y = (self.frame // self.columns) * self.frame_heightrect = Rect(frame_x, frame_y, self.frame_width, self.frame_height)# 将要展示的图片送给image属性,以便展示出来self.image = self.master_image.subsurface(rect)self.old_frame = self.framedef __str__(self):return str(self.frame) + "," + str(self.first_frame) + "," + str(self.last_frame) + \"," + str(self.frame_width) + "," + str(self.frame_height) + "," + \str(self.columns) + "," + str(self.rect)def print_text(font, x, y, text, color=(255, 255, 255), shadow=True):imgText = font.render(text, True, color)screen.blit(imgText, (x, y))def reset_arrow():y = random.randint(250, 350)arrow.position = 800, yif __name__ == "__main__":pygame.init()screen = pygame.display.set_mode((800, 600))pygame.display.set_caption("Escape The Dragon Game")font = pygame.font.Font(None, 18)# 使帧变动按照一定的时间间隔发生framerate = pygame.time.Clock()# 引入背景图片bg = pygame.image.load("background.png").convert_alpha()# 创建一个精灵组group = pygame.sprite.Group()# 创建龙dragon = MySprite(screen)dragon.load("dragon.png", 260, 150, 3)dragon.position = 100, 230group.add(dragon)# 创建玩家player = MySprite(screen)player.load("caveman.png", 50, 64, 8)player.first_frame = 1player.last_frame = 7player.position = 400, 303group.add(player)# 创建箭arrow = MySprite(screen)arrow.load("flame.png", 40, 16, 1)arrow.position = 800, 320group.add(arrow)arrow_vel = 8.0game_over = Falseyou_win = Falseplayer_jumping = Falsejump_vel = 0.0player_start_y = player.Ywhile True:# 将帧速率设置为30framerate.tick(30)# 为精灵动画定时ticks = pygame.time.get_ticks()for event in pygame.event.get():if event.type == QUIT:sys.exit()keys = pygame.key.get_pressed()if keys[K_ESCAPE]:sys.exit()elif keys[K_SPACE]:if not player_jumping:player_jumping = Truejump_vel = -8.0if not game_over:arrow.X -= arrow_velif arrow.X < -40:reset_arrow()# 检测玩家和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, player):reset_arrow()player.X -= 10# 检测龙和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, dragon):reset_arrow()dragon.X -= 10# 检测玩家和龙是否碰撞,即玩家是否会被龙吃了if pygame.sprite.collide_rect(player, dragon):game_over = True# 龙被击中10次则游戏结束if dragon.X < -100:you_win = Truegame_over = Trueif player_jumping:player.Y += jump_veljump_vel += 0.5if player.Y > player_start_y:player_jumping = Falseplayer.Y = player_start_yjump_vel = 0.0screen.blit(bg, (0, 0))if not game_over:group.update(ticks, 50)group.draw(screen)print_text(font, 350, 560, "Press SPACE to jump!")if game_over:print_text(font, 360, 100, "G A M E O V E R")if you_win:print_text(font, 330, 130, "YOU BEAT THE DRAGON!")else:print_text(font, 330, 130, "THE DRAGON GOT YOU!")pygame.display.update()

运行结果如下:

任务一:当玩家跳过箭没有被击中的时候,计分

首先设置两个变量:

score = 0
# 用于判断玩家是否被击中
hit = False

然后在如下地方进行一些修改即可:

        if not game_over:arrow.X -= arrow_velif arrow.X < -40:if not hit:score += 10reset_arrow()# 检测玩家和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, player):hit = Truereset_arrow()player.X -= 10# 检测龙和箭是否碰撞,被击中则往后退if pygame.sprite.collide_rect(arrow, dragon):score += 10reset_arrow()dragon.X -= 10

当然,由于游戏中龙是一定会挡住箭的,因此其实可以不用hit这个变量

Pygame学习笔记6:使用Pygame精灵以及Escape the Dragon相关推荐

  1. pygame 学习笔记(8)精灵动画的实现:子弹的爆炸效果

    本文内容 subsurface() 子 surface的学习 实现一个精灵动画 Note:本文代码基于上一小节,可以直接在上文文末下载工程文件. 在上一节中,我们只是让坦克移动起来,但不是真正的动画, ...

  2. pygame学习笔记(5)——精灵

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 据说在任天堂FC时代,精灵的作用相当巨大,可是那时候只知道怎么玩超级玛丽.魂斗罗,却对精灵一点也不知.pygame ...

  3. 【Pygame 学习笔记】8.精灵

    术语"精灵"是旧计算机和游戏机的保留.这些较旧的盒子无法以足够快的速度绘制和擦除普通图形,使其无法用作游戏.这些机器有特殊的硬件来处理需要快速动画的游戏对象.这些对象被称为&quo ...

  4. Pygame学习笔记 4 —— 时间与运动

        还记得我们在之前的程序中如何让兔子动起来的吗,没错,使用event模块检测键盘事件,改变绘图的坐标,画面刷新后兔子就移动了.接下来我们细说如何精确控制时间和运动. 主要内容: pygame的时 ...

  5. Pygame学习笔记 6 —— 3D游戏

        pygame是是上世纪的产品,虽然不适合最3D游戏,但我可以使用pygame来绘制简单的3D图形,就像在白纸上画立体图形一样. 主要内容: 视觉上的远近.3D空间.绘制一个空间图形 一.视觉上 ...

  6. Python第三方库pygame学习笔记(一)

    Pygame Python最经典的2D游戏开发第三方库,也支持3D游戏开发 Pygame适合用于游戏逻辑验证.游戏入门及系统演示验证 Pygame是一种游戏开发引擎,基本逻辑具有参考价值 pygame ...

  7. Python可视化物理随机过程---pygame学习笔记2

    Python可视化物理随机过程-pygame学习笔记2 文章目录 Python可视化物理随机过程---pygame学习笔记2 一.扩散现象的简单的介绍 二.代码实现 三.运行代码的效果展示 四.总结 ...

  8. pygame 学习笔记(7)添加一个精灵:坦克的移动和旋转

    本文内容 精灵 类的使用 Rect 类的使用 实现一个坦克的移动和旋转 效果演示 添加一个静态坦克 我们已经知道如何创建一个游戏窗口,并设置背景图片,还让游戏程序可以对键盘和鼠标进行响应,接着我们需要 ...

  9. pygame学习笔记——检测鼠标碰到、点击图片

    一.碰到效果实现思路 1.坐标检测 时刻检测鼠标的坐标,有没有移到目标图片的坐标范围内,此方法无法准确描述不规则图像的坐标范围. 2.精灵碰撞检测 创建一个鼠标精灵类,创建鼠标对象,一直跟着鼠标移动, ...

最新文章

  1. linux shell数学计算器,技术|使用 GNU bc 在 Linux Shell 中进行数学运算
  2. SVN工具的使用 和在Eclipse中安装GPD插件:(多步审批流,因此选择使用工作流(JBPM)来实现)...
  3. 领域驱动设计在互联网业务开发中的实践
  4. mysql复杂查询sql_mysql – 复杂的SQL查询,很多很多
  5. STM32 - 定时器的设定 - 基础-04 - 输出波形控制 - PWM 模式
  6. build vue3 后压缩的文件在哪_Vue 3学习:4. 集成vuex
  7. 查看Oracle表中的指定记录在数据文件中的位置
  8. 2018年湖南居民人均可支配收入25241元 出行餐饮成消费热点
  9. 地图看世界,给整个世界画一条“胡焕庸线”
  10. python实现文件上传
  11. vue 图片剪裁插件
  12. 相比于深度学习,传统的机器学习算法难道就此没落了吗,还有必要去学习吗?
  13. 国美易卡使用HTTP连接方式,国美易卡保证客户端状态
  14. centos 安装virt-mannager
  15. 六级单词词组积累(三)
  16. 计算机网络-cisco选择题
  17. Django单元测试类和测试数据回滚
  18. 工作表单元格区域另存为图片
  19. JavaScript中数组indexOf()增强版,返回所有匹配索引的数组
  20. 贝加莱工控机维修主板维修5PC600.SX01-00常见故障排查

热门文章

  1. 不能光会摸鱼,用css3告诉你鱼要怎么养
  2. 标签打印软件如何连接SQL Server数据库打印产品标签
  3. 【数据分析】Pandas入门教程
  4. 火狐浏览器cookieSwap
  5. OpenCV学习之滚动条播放视频
  6. Android第三方登陆之新浪微博Weibo篇(原生登陆授权)
  7. 微软招 UWP 了!
  8. 探访美国创客空间之TechShop:商业化的迷你工厂
  9. 详解容灾架构中的数据复制技术
  10. 首款LGA775平台离子迷你主板登场