专栏首页菩提树下的杨过pygame-KidsCanCode系列jumpy-part16-enemy敌人

pygame-KidsCanCode系列jumpy-part16-enemy敌人

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

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

一、先定义敌人类

 1 # 敌人类
 2 class Mob(pg.sprite.Sprite):
 3     def __init__(self, game):
 4         pg.sprite.Sprite.__init__(self)
 5         self.game = game
 6         self.current_frame = 0
 7         self.last_update = 0
 8         self.image_up = self.game.spritesheet.get_image("flyMan_fly.png")
 9         self.image_down = self.game.spritesheet.get_image("flyMan_jump.png")
10         self.image = self.image_up
11         self.rect = self.image.get_rect()
12         self.rect.centerx = random.choice([-100, WIDTH + 100])
13         self.vx = random.randrange(1, 4)
14         if self.rect.centerx > WIDTH:
15             self.vx *= -1
16         self.rect.y = random.randrange(HEIGHT / 2)
17         self.vy = 0
18         self.dy = 0.5
19 
20     def update(self):
21         self.rect.x += self.vx
22         self.vy += self.dy
23         # 敌人上下移动
24         if abs(self.vy) > 3:
25             self.dy *= -1
26         center = self.rect.center
27         if self.dy < 0:
28             self.image = self.image_up
29         else:
30             self.image = self.image_down
31         self.rect = self.image.get_rect()
32         self.rect.center = center
33         self.rect.y += self.vy
34         # 超出边界自动清除资源
35         if self.rect.left > WIDTH + 100 or self.rect.right < -100:
36             self.kill()

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

二、然后调整main.py

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

 1     def update(self):
 2         self.all_sprites.update()
 3 
 4         # 每隔一定时间,随机加入敌人
 5         now = pg.time.get_ticks()
 6         if now - self.mob_timer > MOB_FREQ + random.choice([-1000, -500, 0, 500, 1000]):
 7             self.mob_timer = now
 8             mob = Mob(self)
 9             # 指定分层
10             self.all_sprites.add(mob, layer=MOB_LAYER)
11             self.mobs.add(mob)
12 
13         # 与敌人的碰撞检测
14         mob_hits = pg.sprite.spritecollide(self.player, self.mobs, False)
15         if mob_hits:
16             self.playing = False
17 
18        ...
19 
20         if self.player.rect.top < HEIGHT / 4:
21             self.player.pos.y += max(abs(self.player.vel.y), 2)
22             # 屏幕滚动时,敌人也要相应的滚动
23             for mob in self.mobs:
24                 mob.rect.top += max(abs(self.player.vel.y), 2)
25                 if mob.rect.top > HEIGHT:
26                     mob.kill()
27            ...

这里有几个小技巧:

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,参考以下代码:

 1     def new(self):
 2         self.score = 0
 3         # 这里换成LayeredUpdates为了体现"分层"效果
 4         self.all_sprites = pg.sprite.LayeredUpdates()
 5         self.platforms = pg.sprite.Group()
 6         self.powerups = pg.sprite.Group()
 7         # 敌人的分组
 8         self.mobs = pg.sprite.Group()
 9         self.player = Player(self)
10         # 指定分层
11         self.all_sprites.add(self.player, layer=PLAYER_LAYER)
12         self.mob_timer = 0

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

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • pygame-KidsCanCode系列jumpy-part2-加速度与摩擦力

    上一节,我们整理了一个游戏开发的新框架(即:Game类),本节将运用这个框架,实现基本的加速度及摩托力效果。

    菩提树下的杨过
  • pygame-KidsCanCode系列jumpy-part15-PowerUp加速器

    这一节我们给游戏增加点额外的奖励,大多数游戏中都会有金币、装备啥的来激励玩家,在jumpy这个游戏中,我们也可以增加类似的道具:加速器。效果图如下:

    菩提树下的杨过
  • pygame-KidsCanCode系列jumpy-part11-角色动画(下)

    接上节继续,上节并没有处理向左走、向右走的动画效果,这节补上,看似很简单,但是有一些细节还是要注意:

    菩提树下的杨过
  • pygame-KidsCanCode系列jumpy-part10-角色动画(上)

    上一节学习如何利用spritesheet加载图片,但是player仍然是一张静态的图片,比较枯燥,我们要让它动起来!

    菩提树下的杨过
  • 我的小工具-远程读卡器web客户端(nodejs+websocket实现实时指令交互)

    之前的小工具,远程读卡器web客户端,实现原理是把读写卡服务装在远程(现场)的电脑上,这样有一些缺点,比如现场电脑必须开启端口映射,让客户端能否访问到。只能写好...

    特立独行的猫a
  • Pytorch实现卷积神经网络训练量化(QAT)

    深度学习在移动端的应用越来越广泛,而移动端相对于GPU服务来讲算力较低并且存储空间也相对较小。基于这一点我们需要为移动端定制一些深度学习网络来满足我们的日常续需...

    BBuf
  • iOS开发实战-时光记账Demo 本地数据库版效果分析Demo地址

    由于主页只是一个展示的时光轴界面,UIScrollView加几个按钮就能完成,需要读取数据库内容,所以我们先把内页-增加账单 完成。

    gwk_iOS
  • 10.带人机对战的五子棋程序

    今天我们带来一个带人机对战功能的五子棋程序。程序基于前面文章中的框架搭建,新增人机对战的策略。程序基于规则进行决策,不考虑禁手,玩家执黑子先行。棋盘规模采用15...

    用户4381798
  • Objective-C AVPlayer播放视频的使用与封装大致效果界面搭建Demo地址

    看下成员变量就知道我怎么搭建的了,这里我将video播放层的size作为参照量,对所有控件的size按照其video的size宽高进行比例缩放

    gwk_iOS
  • 6.wxPython防止窗体重画棋子消失的机制

    可以画图的类中wx.ClientDC不必依赖窗体绘画事件,可以随时实例化,随时画图。但是窗体最小化之后再恢复,重画的窗体上通过wx.ClientDC绘制的棋子会...

    用户4381798

扫码关注云+社区

领取腾讯云代金券