目前为止,Player的站立、行走、跳跃都是动画了,只有跳板(即:Platform类)还是难看的矩形,这节我们把Platform也换成图片:

原来的Platform类长这个样子:

 class Platform(pg.sprite.Sprite):
def __init__(self, x, y, w, h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w, h))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y

如果用图片,就不再需要w,h这个参数了(因为图片自带尺寸大小),所以变成下面这样:

 class Platform(pg.sprite.Sprite):
def __init__(self, game, x, y):
pg.sprite.Sprite.__init__(self)
self.game = game
# 改成加载图片
images = [self.game.spritesheet.get_image("ground_grass_broken.png"),
self.game.spritesheet.get_image("ground_grass_small_broken.png")]
# 随机选一张
self.image = random.choice(images)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y

相应的,最开始初始化的5块platform信息(settings.py)

 # starting platform
PLATFORM_LIST = [(0, HEIGHT - 30, WIDTH, 30),
(WIDTH / 2 - 50, HEIGHT * 0.75, 100, 15),
(WIDTH * 0.12, HEIGHT * 0.5, 60, 15),
(WIDTH * 0.65, 200, 80, 10),
(WIDTH * 0.5, 100, 50, 10)]

调整成:

 # starting platform
PLATFORM_LIST = [(5, HEIGHT - 35),
(WIDTH / 2 - 50, HEIGHT * 0.75),
(WIDTH * 0.12, HEIGHT * 0.5),
(WIDTH * 0.65, 200),
(WIDTH * 0.5, 100)]

同时,调整下Player出场时的位置,让它站在最底面的第1块板上:

class Player(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
...
self.rect = self.image.get_rect()
# 初始化时,停在第一块platform上
self.rect.center = (35, HEIGHT - 35)
self.pos = self.rect.center
...

main.py里的new函数,也做相应的调整:

    def new(self):
self.score = 0
... for plat in PLATFORM_LIST:
# 这里相应调整
p = Platform(self, *plat)
...

main.py中的update函数里,最后再调整一下:

     def update(self):
self.all_sprites.update()
... while len(self.platforms) <= 5:
width = random.randrange(50, 100)
# 这里也做相应调整
p = Platform(self, random.randint(0, WIDTH - width),
random.randint(-70, -30))
self.platforms.add(p)
...

跑起来看看,基本效果出来了,难看的矩形终于没有了,但是仔细观察下,漏洞百出,比如下面这些:

问题1:跳板太靠右,边界跑到屏幕外了

修复方法:

检测下platform的right值,如果超出边界,向左挪一点

     def new(self):
... for plat in PLATFORM_LIST:
p = Platform(self, *plat)
# 如果platform位置太靠右,跑出屏幕外,校正位置
if p.rect.right >= WIDTH:
p.rect.centerx = p.rect.centerx - (p.rect.right - WIDTH) - 2
...

问题二:platform把player实例给挡住了

类似photoshop的图层一样,pygame里也有layer的概念,最后绘制的对象,默认在最上层

修复方法:main.py的draw函数,在最后,强制再绘制一次player(tips: 其实有更好的办法,利用图层概念,可参考part17部分

     def draw(self):
self.screen.fill(LIGHT_BLUE)
self.all_sprites.draw(self.screen)
self.debug()
self.draw_text(str(self.score), 22, WHITE, WIDTH / 2, 15)
# 强制把player放在最上层
self.screen.blit(self.player.image, self.player.rect)
pg.display.update()

问题三:跳板叠在一起

解决方法:

思路:随机生成的新跳板,先不急着加入self.platforms,而是运用碰撞检测原理,与现有跳板做碰撞检测(叠在一起,肯定就碰撞上了),如果碰撞了,就扔掉(pygame下一帧会重新生成,如此循环,直到满足条件的跳板加入)

     def update(self):
self.all_sprites.update()
...
# 跳板数<5,且player未跌落到屏幕外(否则player跌到屏幕外,仍在不停做碰撞检测,性能开销极大,会把程序卡死)
while len(self.platforms) <= 5 and self.player.rect.bottom < HEIGHT:
width = random.randrange(50, 100)
# 这里也做相应调整
p = Platform(self, random.randint(0, WIDTH - width),
random.randint(-70, -30))
if p.rect.right >= WIDTH:
p.rect.centerx = p.rect.centerx - (p.rect.right - WIDTH) - 2
self.all_sprites.add(p)
# 防止二个plat平台叠在一起(原理:用待加入的plat与其它platform实例做碰撞检测,如果碰撞了,则扔掉)
hits = pg.sprite.spritecollideany(p, self.platforms)
if hits:
p.kill()
else:
self.platforms.add(p)

问题四: player已经超过了屏幕顶端,但是屏幕并没有向上滚动,这样玩家就无法看到头顶的新跳板。

解决办法:

先来分析下main.py中update函数中的滚动处理

        if self.player.rect.top < HEIGHT / 4:
self.player.pos.y += abs(self.player.vel.y)
for plat in self.platforms:
plat.rect.top += abs(self.player.vel.y)
if plat.rect.top > HEIGHT:
...

如果player的y轴速度为0,abs函数算出来的值为0,所以跳板与兔子的y坐标值并不会动(也就是屏幕无法滚动),改进为下面这样:

     def update(self):
self.all_sprites.update()
...
if self.player.rect.top < HEIGHT / 4:
# 防止垂直方向速度为0时,无法滚动屏幕
self.player.pos.y += max(abs(self.player.vel.y), 2)
for plat in self.platforms:
plat.rect.top += max(abs(self.player.vel.y), 2)
if plat.rect.top > HEIGHT:
...

修复了上面这一堆bug后,再来运行下:

源码: https://github.com/yjmyzz/kids-can-code/tree/master/part_12

pygame-KidsCanCode系列jumpy-part12-platform图片的更多相关文章

  1. 前端工程师技能之photoshop巧用系列第四篇——图片格式

    × 目录 [1]图片格式 [2]保存设置 前面的话 对于前端来说,图片格式是需要重要掌握的知识.本文是photoshop巧用系列第四篇——图片格式 图片格式 目前在前端的开发中常用的图片格式有jpg. ...

  2. WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

    原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统, ...

  3. 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  4. iOS开发系列--无限循环的图片浏览器

    --UIKit之UIScrollView 概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件 ...

  5. 12LaTeX学习系列之---LaTex的图片插入

    目录 目录 前言 (一)插图的基本语法 (二)插入的基本设置 1.说明: 2.源代码: 3.输出效果 (三)查看文档 目录 本系列是有关LaTeX的学习系列,共计19篇,本章节是第12篇. 前一篇:1 ...

  6. Android批量图片加载经典系列——afinal框架实现图片的异步缓存加载

    一.问题描述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存加载(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html# ...

  7. Android批量图片载入经典系列——afinal框架实现图片的异步缓存载入

    一.问题描写叙述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存载入,接下来我们再介绍一下afinal 框架的使用. Afinal 是一个android的http框架.sql ...

  8. android图像处理系列之七--图片涂鸦,水印-图片叠加

    图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可.前面在android图像处理系列之六--给图片添加边框(下)-图片叠加中也讲到了图片叠加,里面实现的原理是直接操 ...

  9. pygame征途:(一)图片移动反弹

    题目大意: 就是弄一张图片在背景画布上移动,然后碰到边界就图片翻转并且反向移动 基本思路: 需要pygame常用的一些常用的函数,然后基本就是在背景画布上blit一张图片,然后移动就是先全刷成背景画布 ...

  10. Caffe学习系列(15):计算图片数据的均值

    图片减去均值后,再进行训练和测试,会提高速度和精度.因此,一般在各种模型中都会有这个操作. 那么这个均值怎么来的呢,实际上就是计算所有训练样本的平均值,计算出来后,保存为一个均值文件,在以后的测试中, ...

随机推荐

  1. JMeter中BeanShell断言使用一

    Jmeter Ant Task如何让beanshell断言失败的详细信息展示在report里面 首先必须给beanshell断言添加FailureMessage if(${TotalClient_SS ...

  2. 关于java中的伪共享的认识和解决

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素: CPU缓存 网页浏览器为了加快速度,会在本机存缓存以前浏览过 ...

  3. js判断手机邮箱格式(正则)

    function fun() { var realname = document.getElementById("realname"); var telephone = docum ...

  4. Json传递数据两种方式(json大全)

    1.Json传递数据两种方式(json大全)----------------------------字符串 var list1 = ["number","name&quo ...

  5. day8数据类型补充,集合,深浅拷贝

    思维导图: 集合的补充:下面的思维导图有一个点搞错了,在这里纠正一下,没有合集,是反交集,^这个是反差集的意思 . 交集&,反交集^,差集-,并集|,然后就是子集和超集 数据类型补充: ''' ...

  6. Linux下C语言的socket网络编程

    关于详细的服务器建立的步骤以及相关的socket套接字的知识我已经在python socket编程的文章中提到过了,大家可以参看那一篇博客来历接socket套接字编程的内容,由于要是用C相关的API所 ...

  7. 解决Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another proce...

    解决Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another proce... ...

  8. 牛客练习赛A 【BFS】

    <题目链接> 题目大意: 给出一张图,问你其中 ' # ' 加上那些不能够到达边界的 ' . ' 的点的个数,' # ' 会起阻挡作用. 解题分析: 本题很好做,无非就是将所有能够由边界上 ...

  9. python专题 --- 递归

    如果一个函数在函数内部调用自身本身,这个函数就是递归函数 举例如阶乘函数,其数学递归定义如下: 对应的算法实现 def fact(n): if n==1: return 1 return n * fa ...

  10. Diango之通过form表单向服务端发送数据

    通过form表单向服务端发送数据 表单元素 表单:form></form>表单用于向服务器传输数据.另外一种向服务端传输数据的方式为ajax. form属性: action:提交表单 ...