zoukankan      html  css  js  c++  java
  • 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()
    View Code

    代码并不复杂,要注意的地方,已经加了注释,注意下坐标的初始化处理。在[-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            ...
    View Code

    这里有几个小技巧:

    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
    View Code

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

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

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

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

  • 相关阅读:
    xUtils 中的BitmapUtils 全面注释
    321影音代码
    android studio使用技巧
    java android面试题分析总结
    android面试题分析总结
    据说年薪30万的Android程序员必须知道的帖子
    好用软件
    win10找回win7的windows照片查看器
    github上传代码
    android 常见错误集锦
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/pygame-kidscancode-part16-enemy.html
Copyright © 2011-2022 走看看