项目详细介绍
在这个系列中,将制作一个雷霆战机游戏。
添加血条
现在,玩家被一次敌机击中后摧毁。这不是很有趣,所以要为玩家添加一个属性shield,数值类型,范围0 - 100。
class Player(pygame.sprite.Sprite): def __init__(self): self.speedx = 0 self.shield = 100
现在,每次玩家被流星击中时,都可以从血条中减去一点。当血条达到0时,玩家将被摧毁。为了让事情更有趣,可以通过使用敌机的radius属性使大型敌机比小型敌机造成更大的伤害。
破坏玩家
目前,mob-versus-player碰撞代码非常简单:
# check to see if a mob hit the player hits = pygame.sprite.spritecollide(player, mobs, False, pygame.sprite.collide_circle) if hits: running = False
改成:
# check to see if a mob hit the player hits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle) for hit in hits: player.shield -= hit.radius * 2 if player.shield <= 0: running = False
改变了spritecollide函数的第三个参数(False改为了True),希望流星碰到后自动删除,因为如果不这样做,那么敌机将继续存在,当它移动时,下一帧会和玩家发生另一次碰撞,依此类推。
此外,玩家可能同时碰到多个敌机,因此hits可以有多个项目。循环hits,根据每个敌机半径扣除玩家每次被碰到后失去的血条。最后,如果玩家的血条达到0,游戏将结束。
由于正在删除任何击中玩家的怪物,正在减少游戏中的怪物总数。希望保持不变,所以每当移除一个时,需要产生一个新的暴徒。初始化时这样产生了怪物集合:
for i in range(8): m = Mob() all_sprites.add(m) mobs.add(m)
每当移除一个怪物时,需要做同样的事情,这是重复的代码,定义一个函数:
def newmob(): m = Mob() all_sprites.add(m) mobs.add(m)
现在可以在游戏开始时调用该功能,当子弹击中暴徒时调用该功能,以及当需要更换击中玩家的暴徒时调用该功能:
for i in range(8): newmob() # check to see if a bullet hit a mob hits = pygame.sprite.groupcollide(mobs, bullets, True, True) for hit in hits: score += 50 - hit.radius random.choice(expl_sounds).play() newmob() # check to see if a mob hit the player hits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle) for hit in hits: player.shield -= hit.radius * 2 newmob() if player.shield <= 0: running = False
有血条变量的值,而且它有效,但除非玩家能看到这个值,否则它不是很有用。需要创建一个显示,但不是只显示数字,将制作一个条形图,显示血条的满/空:
def draw_shield_bar(surf, x, y, pct): if pct < 0: pct = 0 BAR_LENGTH = 100 BAR_HEIGHT = 10 fill = (pct / 100) * BAR_LENGTH outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT) fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT) pygame.draw.rect(surf, GREEN, fill_rect) pygame.draw.rect(surf, WHITE, outline_rect, 2)
此函数与draw_text之前定义的函数类似。它接受位置参数(x, y)和填充量参数pct。将绘制两个矩形:第一个是白色轮廓,第二个是绿色填充部分。在游戏循环的绘图部分添加了对此函数的调用:
draw_text(screen, str(score), 18, WIDTH / 2, 10) draw_shield_bar(screen, 5, 5, player.shield)