You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame游戏结束功能实现问题:分数达标后无法停止及屏幕闪烁

解决你的小游戏停止与闪烁问题

嘿,我看你这个收集类小游戏遇到了两个棘手的问题:分数到100后游戏没法停止,还出现了屏幕闪烁的情况。咱们一步步来搞定这些问题!

问题根源分析

1. 游戏无法停止

你当前的代码里,当score >= 100时调用endoflevel1(),但Pygame(或者你用的Pygame Zero框架)的update()和draw()函数会持续循环执行——哪怕你显示了结束界面,后续的update()还是会继续处理角色移动、碰撞逻辑,draw()也会重新绘制游戏界面,直接把结束界面覆盖掉,所以你根本看不到结束状态,游戏也停不下来。

2. 屏幕闪烁

闪烁的原因是你在endoflevel1()里手动调用了pygame.display.flip(),但框架本身已经在自动处理屏幕刷新了,手动刷新和自动刷新冲突,就会导致画面闪烁。另外,draw()里的screen.clear()和screen.blit()的顺序如果处理不好,也可能加重闪烁。

解决方案(不用while循环,用状态控制)

我们不需要额外加while循环,框架本身已经有事件循环了,只需要加一个游戏状态变量来控制游戏处于“运行中”还是“已结束”状态,然后在update()和draw()里根据这个状态执行不同逻辑。

步骤1:添加游戏状态变量

在全局变量区域添加:

game_active = True  # 控制游戏是否处于运行状态

步骤2:修改update函数,让游戏结束时停止逻辑

在update()函数开头加上判断,游戏结束时直接返回,不再处理后续逻辑:

def update():
    global score, game_active
    if not game_active:
        return  # 游戏已结束,跳过所有游戏逻辑

    # 下面保留原来的移动、碰撞逻辑...

步骤3:修改draw函数,根据状态绘制界面

把结束界面的绘制逻辑移到draw()里,代替原来的endoflevel1()函数,这样框架能统一处理刷新,避免闪烁:

def draw():
    if game_active:
        screen.clear()
        screen.blit("background", (0,0))
        apple.draw()
        pear.draw()
        plum.draw()
        donut.draw()
        ice.draw()
        chips.draw()
        happysmiley.draw()
        screen.draw.text("Punkte: " + str(score), (700, 5), color = "black")
    else:
        # 绘制结束界面
        screen.fill("green")
        screen.draw.text("Game Over: Du hast das 1. Level erfolgreich abgeschlossen!", topleft=(100,350), fontsize=30)

步骤4:修改分数达标后的逻辑

原来的endoflevel1()可以删掉,改成直接设置game_active = False:

if score >= 100:
        game_active = False
        # 可以在这里添加结束音效、停止背景音乐等逻辑
        pygame.mixer.music.stop()

步骤5:修复碰撞检测的小bug

你代码里chips的碰撞判断写错了,把chips.x写成了chips.y:

# 错误代码:
if happysmiley.collidepoint (chips.y, chips.y):
# 改成:
if happysmiley.collidepoint(chips.x, chips.y):

额外优化:简化重复的食物移动逻辑

你现在每个食物的移动和重置逻辑都是重复的,可以把所有食物放到一个列表里,用循环处理,让代码更简洁:

# 替换原来的单个Actor定义
foods = [
    Actor("apple"),
    Actor("pear"),
    Actor("plum"),
    Actor("donut"),
    Actor("ice"),
    Actor("chips")
]

# 初始化所有食物的位置
for food in foods:
    food.pos = randint(0, 800), randint(-800, 0)

# 在update()里替换原来的多个if判断
for food in foods:
    if food.y < 800:
        food.y += 4
    else:
        food.pos = randint(0, 800), randint(-800, 0)

修改后的完整代码

from random import randint
import pygame

WIDTH = 800
HEIGHT = 800

# 初始化食物列表,简化重复代码
foods = [
    Actor("apple"),
    Actor("pear"),
    Actor("plum"),
    Actor("donut"),
    Actor("ice"),
    Actor("chips")
]
for food in foods:
    food.pos = randint(0, 800), randint(-800, 0)

happysmiley = Actor("happysmiley")
happysmiley.pos = 300, 750

score = 0
game_active = True  # 游戏状态控制变量

background = pygame.image.load("images\\background.png")
pygame.mixer.init()
pygame.mixer.music.load("music\\funmusic.mp3")
pygame.mixer.music.play(-1)

def draw():
    if game_active:
        screen.clear()
        screen.blit("background", (0,0))
        for food in foods:
            food.draw()
        happysmiley.draw()
        screen.draw.text("Punkte: " + str(score), (700, 5), color = "black")
    else:
        screen.fill("green")
        screen.draw.text("Game Over: Du hast das 1. Level erfolgreich abgeschlossen!", topleft=(100,350), fontsize=30)

def update():
    global score, game_active
    if not game_active:
        return  # 游戏结束,停止所有逻辑

    # 处理食物移动
    for food in foods:
        if food.y < 800:
            food.y += 4
        else:
            food.pos = randint(0, 800), randint(-800, 0)

    # 处理玩家移动
    if keyboard.left:
        happysmiley.x -= 5
    elif keyboard.right:
        happysmiley.x += 5

    # 处理碰撞逻辑
    for food in foods:
        if happysmiley.collidepoint(food.x, food.y):
            # 根据食物类型更新分数和音效
            if food.image == "apple":
                score += 2
                effect = pygame.mixer.Sound("sounds\\bonus.wav")
            elif food.image in ["pear", "plum"]:
                score += 1
                effect = pygame.mixer.Sound("sounds\\bonus.wav")
            else:  # donut, ice, chips
                score -= 1
                effect = pygame.mixer.Sound("sounds\\no.wav")
            effect.play()
            # 碰撞后重置食物位置
            food.pos = randint(0, 800), randint(-800, 0)

    # 检查是否达标结束游戏
    if score >= 100:
        game_active = False
        pygame.mixer.music.stop()

这样修改后,游戏分数到100时会立刻停止所有游戏逻辑,显示结束界面,而且不会出现闪烁问题啦!

内容的提问来源于stack exchange,提问作者yellowcake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:49:29