目前为止,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. 【Android】Android 广播大全

    [Android]Android 广播大全 String ADD_SHORTCUT_ACTION 动作:在系统中添加一个快捷方式. String ALL_APPS_ACTION 动作:列举所有可用的应 ...

  2. Codeforces 356D Bacterial Melee dp

    Bacterial Melee 我们发现所有合法串都是原序列的某个子序列(这个子序列相邻元素相等) 的扩展, 比如子序列为abc, 那么aabbbc, abbbcc 等都是合法串. 所以我们只需要dp ...

  3. 黑色半透明镂空遮罩指引效果实现jQuery小插件

    /*! * by zhangxinxu(.com) 2017-05-18 * 新版上线时候的黑色半透明镂空遮罩指引效果实现jQuery小插件 * 兼容到IE8+ * MIT使用协议,使用时候保留版权 ...

  4. HTML元素粘滞融合效果

    .target { filter: url("#goo"); } .ball { width: 150px; height: 150px; border-radius: 50%; ...

  5. Codeforces 177G2 Fibonacci Strings KMP 矩阵

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF117G2.html 题目传送门 - CF177G2 题意 定义斐波那契字符串如下: $s_1="a ...

  6. F. Shovels Shop 背包DP

    题意: 商店里有n把铲子 每个铲子有其标价 一个人要买k吧 有m个优惠政策 每个优惠政策有两个元素x,y 表示   正好买x个铲子的时候  这x个铲子中最便宜的y个铲子免单 求用最少的前买到k个铲子 ...

  7. NiftyNet开源平台使用

    NiftyNet是一款开源的卷积神经网络平台,专门针对医学图像处理分析,上一篇博客已经详细介绍了这个平台,接下来让我简单介绍一下目前我了解到的使用方法.更详细的使用方法.以及配置过程请查看NiftyN ...

  8. puppeteer 安装失败的解决方案

    你应该也是在玩puppeteer,所以才会来到这里寻找答案,开始正文…… 安装时遇到 ERROR: Failed to download Chromium r515411! Set "PUP ...

  9. Jenkins不同job之间传递参数

    有的时候不同job直接需要传递一个文件名或者路径,这个时候我们不需要传递文件实体,那这个路径如何传递呢?比如有如下两个项目,我想把A的工作目录传递给B,让B使用. A job配置 首先需要安装一个Pa ...

  10. sql语句(一)— —判断是否有这条数据的优化

    今天发现一个业务上的存储过程写的不够完善,和老板反应后,老板说你来完善吧,我:苦瓜脸~.说实话,我对SQL语句的熟练程度真的是不提也罢[捂脸],大概的判断流程我知道,但是真的让我自己写,还真得上网查查 ...