上回继续,这次我们要给游戏加点难度,增加几个随机出现的敌人,玩家碰到敌人后Game Over。

最终效果如下,头上顶个"电风扇"的家伙,就是敌人。

一、先定义敌人类

 # 敌人类
class Mob(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.current_frame = 0
self.last_update = 0
self.image_up = self.game.spritesheet.get_image("flyMan_fly.png")
self.image_down = self.game.spritesheet.get_image("flyMan_jump.png")
self.image = self.image_up
self.rect = self.image.get_rect()
self.rect.centerx = random.choice([-100, WIDTH + 100])
self.vx = random.randrange(1, 4)
if self.rect.centerx > WIDTH:
self.vx *= -1
self.rect.y = random.randrange(HEIGHT / 2)
self.vy = 0
self.dy = 0.5 def update(self):
self.rect.x += self.vx
self.vy += self.dy
# 敌人上下移动
if abs(self.vy) > 3:
self.dy *= -1
center = self.rect.center
if self.dy < 0:
self.image = self.image_up
else:
self.image = self.image_down
self.rect = self.image.get_rect()
self.rect.center = center
self.rect.y += self.vy
# 超出边界自动清除资源
if self.rect.left > WIDTH + 100 or self.rect.right < -100:
self.kill()

代码并不复杂,要注意的地方,已经加了注释,注意下坐标的初始化处理。在[-100,100]的x坐标,[0,HEIGHT/2]的y坐标范围内,随机选1个位置,让敌人出现,然后为了有上下振动的的效果,update中对y轴速度有一个偏移量dy的处理。

二、然后调整main.py

update函数中每隔一定时间,加入敌人

     def update(self):
self.all_sprites.update() # 每隔一定时间,随机加入敌人
now = pg.time.get_ticks()
if now - self.mob_timer > MOB_FREQ + random.choice([-1000, -500, 0, 500, 1000]):
self.mob_timer = now
mob = Mob(self)
# 指定分层
self.all_sprites.add(mob, layer=MOB_LAYER)
self.mobs.add(mob) # 与敌人的碰撞检测
mob_hits = pg.sprite.spritecollide(self.player, self.mobs, False)
if mob_hits:
self.playing = False ... if self.player.rect.top < HEIGHT / 4:
self.player.pos.y += max(abs(self.player.vel.y), 2)
# 屏幕滚动时,敌人也要相应的滚动
for mob in self.mobs:
mob.rect.top += max(abs(self.player.vel.y), 2)
if mob.rect.top > HEIGHT:
mob.kill()
...

这里有几个小技巧:

2.1 敌人出现的频度,可以调整MOB_FREQ 这个常量,它在settings.py中定义

# enemy
MOB_FREQ = 8000

表示每8秒左右出现一个敌人,然后为了更具随机性,if条件中还加入了random.choice([-1000, -500, 0, 500, 1000]),所以最终敌人出现的时间间隔,实际是 7.0s、7.5s、8.0s、8.5s、9s 中某一个。

2.2 兔子向上跳,所有档板向下滚动时,敌人也要同步向下滚动,不然画面会不太自然(有兴趣的可以把这一段去掉试试)

2.3 为了防止敌人,被档板、加速器之类的给遮挡住,这里我们使用了pygame中的分层概念。其实就是类似ps中的图层概念,层越高的对象,就越在最上面。即:层"低"的对象,会被层"高"的对象遮挡掉。

为了使用分层,all_sprites必须换成LayeredUpdates,参考以下代码:

     def new(self):
self.score = 0
# 这里换成LayeredUpdates为了体现"分层"效果
self.all_sprites = pg.sprite.LayeredUpdates()
self.platforms = pg.sprite.Group()
self.powerups = pg.sprite.Group()
# 敌人的分组
self.mobs = pg.sprite.Group()
self.player = Player(self)
# 指定分层
self.all_sprites.add(self.player, layer=PLAYER_LAYER)
self.mob_timer = 0

这些分层值,同样可以定义在settings.py中

 # layer
PLAYER_LAYER = 4
MOB_LAYER = 3
PLATFORM_LAYER = 1
POWERUP_LAYER = 2

细心的朋友可能发现一个问题:兔子与敌人的碰撞检测貌似有点怪,明明还差着一些距离,就认为碰上了。这个问题,下节我们再来讨论改进办法。

源码参考:https://github.com/yjmyzz/kids-can-code/tree/master/part_16

pygame-KidsCanCode系列jumpy-part16-enemy敌人的更多相关文章

  1. pygame 笔记-7 生命值/血条处理

    通常游戏中的角色都有所谓的生命值,而且头顶上会有一个血条显示.生命值无非就是一个属性而已,很容易在Player.py类中增加,头顶上的血条其实就是绘制二个矩形,叠加在一起. 以上节的Player.py ...

  2. 炸掉你的城堡!(pygame獾兔大战)

    代码修改bug,添加注释等,獾的速度加快之后很难-- git地址: https://github.com/Jailman/blowupyrcastle.git 游戏资源使用了文章中附带的下载,原版文章 ...

  3. 使用pygame开发一个弹幕射击游戏(一)

    本文作为开发过程记录用. 目前游戏画面: 下一个添加的功能:敌机可以进行射击. 弹幕类 from pygame.sprite import Sprite from pygame import tran ...

  4. 2015/11/7用Python写游戏,pygame入门(7):碰撞检测

    我们已经完成了飞机大战的大部分东西,但是游戏还是没有办法正式开玩,因为子弹并不能打掉飞机.只有完成了这一个工作,游戏才算基本成型. 今天的内容就非常简单了,就是做到这个碰撞检测,以及控制好子弹和飞机的 ...

  5. SurvivalShooter学习笔记(八.敌人管理器)

    敌人管理器:管理敌人的随机出生点创建 在场景中建立几个空物体,作为敌人的出生点 public class EnemyManager : MonoBehaviour { public PlayerHea ...

  6. 12岁的少年教你用Python做小游戏

    首页 资讯 文章 频道 资源 小组 相亲 登录 注册       首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...

  7. 青少年如何使用 Python 开始游戏开发

    这是一篇由教程团队成员Julian Meyer发表的文章,一个12岁的python开发人员.你可以在Google+和Twitter上找到他. 你可曾想过如何创建视频游戏吗?它不像你想象的那么复杂! 在 ...

  8. 使用 Python 开始游戏开发

    使用 Python 开始游戏开发 这是一篇由教程团队成员Julian Meyer发表的文章,一个12岁的python开发人员.你可以在Google+和Twitter上找到他. 你可曾想过如何创建视频游 ...

  9. Python制作的射击游戏

    如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线.] 你有没有想过电脑游戏是怎样制作出来的?其实它没有你想象的那样复杂! 在这个教程里,你要学做一个叫<兔子和獾>的塔防游戏,兔子作 ...

  10. 越狱Season 1- Episode 16

    Season 1, Episode 16 -Burrows:Don't be. It's not your fault. 不要,不是你的错 -Fernando: Know what I like? 知 ...

随机推荐

  1. JavaScript动态加载CSS和JS文件

    var dynamicLoading = { css: function(path){ if(!path || path.length === 0){ throw new Error('argumen ...

  2. alpha冲刺5/10

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:冲刺5 团队部分 后敬甲(组长) 过去两天完成了哪些任务 文字描述 最近事情有点多,只是跟进了下进度,写了写博客 接下来 ...

  3. zabbix分布式监控的部署与win被控端

    zabbix是一个分布式监视,管理系统,基于server-clinet架构,可用于监视各种网络服务,服务器和网络机器等状态. server端基于C语言,web管理端Frontend则是基于PHPA制作 ...

  4. NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序

    原文链接https://www.cnblogs.com/zhouzhendong/p/9258043.html 题目传送门 - 洛谷P3953 题目传送门 - Vijos P2030 题意 给定一个有 ...

  5. IDEA链接mySql问题 : You have an error in your SQL syntax : 'OPTION SQL_SELECT_LIMIT=1000' (or 'OPTION SQL_SELECT_LIMIT=DEFAULT')

    IDEA控制台错误信息: check the manual that corresponds to your MySQL server version for the right Code: 1064 ...

  6. Hudson与Jenkins

    Hudson是Jenkins的前身,它们都是基于Java开发的一种持续集成工具,用于监控程序重复的工作,包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. Hudson的特性 1 ...

  7. 【python】廖雪峰python教程学习--基础

     No1: 目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的 No2: 用r''表示''内部的字符串默认不转义 No3: 以'''开头,敲回车可以换行 No4: 布尔 ...

  8. Tallest Cow POJ - 3263 (区间点修改)

    FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positi ...

  9. POJ 2823 Sliding Window​ (模板题)【单调队列】

    <题目链接> <转载于>>> > 题目大意: 给你一段序列和一个长为k的窗口,这个窗口从最左边逐渐向右滑,直到滑到最右边,问你,该窗口在滑动的过程中,最大值和 ...

  10. java接口签名(Signature)实现方案续

    一.前言 由于之前写过的一片文章 (java接口签名(Signature)实现方案 )收获了很多好评,此次来说一下另一种简单粗暴的签名方案.相对于之前的签名方案,对body.paramenter.pa ...