添加生命值
现在,我们的玩家被一颗Mob流星击中即被摧毁,这有点悲催,所以我们要为我们的玩家添加一个属性:生命值,它只是从 0 到 100 的数字。
class Player(pygame.sprite.Sprite):
def __init__(self):
self.speedx = 0
self.shield = 100
现在,每次玩家被流星Mob击中时,我们都可以从生命值中减去一点。 当生命值为 0 时,玩家被摧毁。 为了让事情变得更有趣,我们可以通过使用流星的半径属性使大流星比小流星造成更大的伤害。
摧毁玩家
目前,我们的 Mob 和 玩家 的碰撞代码非常简单:
# 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,则游戏结束。
您可能已经注意到的一件事是,由于我们在游戏中删除了任何击中玩家的Mob,因此游戏中的Mob总数也是减少的。 我们希望它保持不变,所以每当我们移除一个Mob时,我们都需要生成一个新Mob。 我们生成了这样的原始Mobs:
for i in range(8):
m = Mob()
all_sprites.add(m)
mobs.add(m)
因为我们需要重复使用以上的代码来产生一个新的Mob,所以,我们把创建Mob的代码放到一个函数中,这样可以在任何需要的时候调用它:
def newmob():
m = Mob()
all_sprites.add(m)
mobs.add(m)
现在我们可以在游戏开始部分调用该函数。当我们击中一个Mob时,以及当我们需要替换和玩家相碰撞的Mob时:
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()
函数类似。 它将通过 BAR_HEIGHT 绘制一个长度为 BAR_LENGTH 的条形图,位于 (x, y) 处并填充 pct 数量。 我们将绘制两个矩形:第一个是白色轮廓,第二个是绿色填充部分。 我们在游戏循环的绘图部分添加对这个函数的调用:
draw_text(screen, str(score), 18, WIDTH / 2, 10)
draw_shield_bar(screen, 5, 5, player.shield)