一、引言
前面教程中已经实现游戏的基本功能,但游戏只有得分,没有失败惩罚的功能,显然比较无趣。本节中, 我们尝试增加游戏失败功能,当红色方块出界时,游戏为结束状态,在界面中间显示“GAME OVER”的文字。
二、实现思路
红色方块出界游戏就失败
前面的例子中,我们很容易找到红色方块出界需要在哪里判断增加代码。
if red_y >= 300:
red_y = 0
red_x = random.randint(50, 350)
当red_y变量大于300时,就说明红色方块出界,我们在此处增加显示“GAME OVER”文字,这部分的功能应该跟前面显示分数的功能类似,同学们一定要学会举一反三,将前面代码copy后进行修改,我们只需要修改文字的内容、字体、颜色,就可以完成功能。
代码如下:
import pygame, sys
import random
# 初始化
pygame.init()
SCREEN = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')
# 绿色方块固定在最下方,左右移动,y值不变
green_x = 110
# 红色方块从上往下移动,x值不变
red_y = 0
# 游戏主循环
score = 0
pygame.font.init()
myfont = pygame.font.Font(None,60)
red_x = 35
while True:
for event in pygame.event.get():
# 处理退出事件
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 键盘按下事件
elif event.type == pygame.KEYDOWN:
# 'a'键被按下
if event.key == pygame.K_a:
green_x -= 5
elif event.key == pygame.K_d:
green_x += 5
red_y += 5
green_rect = pygame.Rect(green_x, 250, 100, 50)
if green_rect.colliderect(red_x, red_y, 20, 50):
print('红色方块与绿色方块碰撞到了')
# 为了方便看到碰撞结果,直接break返回
score += 1
red_y = 0
red_x = random.randint(50, 350)
if red_y >= 300:
gameOverTextImage = myfont.render('GAME OVER!', True, (0, 0, 255))
SCREEN.blit(gameOverTextImage, (80,150))
SCREEN.fill((255, 255, 255))
# 调用 pygame.display.update() 方法更新整个屏幕的显示
pygame.draw.rect(SCREEN, (255, 0, 0), (red_x, red_y, 20, 50))
pygame.draw.rect(SCREEN, (0, 255, 0), (green_x, 250, 100, 50))
textImage = myfont.render("score: " + str(score), True, (255, 0, 0))
SCREEN.blit(textImage, (10,10))
pygame.display.update()
pygame.time.delay(50)
小伙伴把代码复制到idle编辑后运行,当红色方块出界时,并没有看到文字出现。当代码运行结果与预期不一致,小伙伴一定不要着急,要仔细调试代码。调试代码来说,最有效的方式有两个:1、阅读源代码;2、在相关代码增加打印,观察重要变量的值,找出与预期不一致的地方,思考是什么样的原因可能引起这些异常。
上面的代码我们无法显示出“GAME OVER”文字是因为,我们先画出结束文字,后面的代码再调用SCREEN.fill函数把背景填充成白色,此时将我们画出来的文字覆盖了。一种粗暴解决这个问题的方法,将SCREEN.fill这一行代码改在
if red_y >= 300 这一行之前。但这种写法我们把画图跟逻辑判断的代码混在一起,比较不好。我们来尝试这么写,用is_over变量来表示游戏是否结束,逻辑判断时把状态保存到该变量,画图画界面时利用这个变量来判断是否需要再显示相关文字。
实现代码如下:
import pygame, sys
import random
# 初始化
pygame.init()
SCREEN = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')
# 绿色方块固定在最下方,左右移动,y值不变
green_x = 110
# 红色方块从上往下移动,x值不变
red_y = 0
# 游戏主循环
score = 0
pygame.font.init()
myfont = pygame.font.Font(None,60)
red_x = 35
is_over = False
while True:
for event in pygame.event.get():
# 处理退出事件
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 键盘按下事件
elif event.type == pygame.KEYDOWN:
# 'a'键被按下
if event.key == pygame.K_a:
green_x -= 5
elif event.key == pygame.K_d:
green_x += 5
red_y += 5
green_rect = pygame.Rect(green_x, 250, 100, 50)
if green_rect.colliderect(red_x, red_y, 20, 50):
print('红色方块与绿色方块碰撞到了')
# 为了方便看到碰撞结果,直接break返回
score += 1
red_y = 0
red_x = random.randint(50, 350)
if red_y >= 300:
is_over = True
SCREEN.fill((255, 255, 255))
# 调用 pygame.display.update() 方法更新整个屏幕的显示
pygame.draw.rect(SCREEN, (255, 0, 0), (red_x, red_y, 20, 50))
pygame.draw.rect(SCREEN, (0, 255, 0), (green_x, 250, 100, 50))
textImage = myfont.render("score: " + str(score), True, (0, 0, 255))
SCREEN.blit(textImage, (10,10))
if is_over:
gameOverTextImage = myfont.render('GAME OVER!', True, (255, 0, 0))
SCREEN.blit(gameOverTextImage, (80,150))
pygame.display.update()
pygame.time.delay(50)
游戏结束画面.png
三、思考题
- 考虑如何增加功能,每个玩家有三条命,每次红色方块出界时消耗一个生命,当生命值为0时,才判定游戏失败。
- 游戏结束时的文字,不是刚好在中间,思考怎么样才能让"GAME OVER"的文字局中。
网友评论