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

如何修复Pygame暂停函数的两个异常:跳跃清零分数、暂停涨分

Pygame暂停功能的分数异常修复方案

问题现象

  • 玩家跳跃时分数被清零
  • 进入暂停界面后分数持续增长

问题根源

  1. 跳跃清零分数:全局事件处理中,所有SPACE按键都会触发start_time重置,包括玩家跳跃时的SPACE输入,导致分数计算的时间基准被重新设置。
  2. 暂停时分数增长:暂停状态下没有暂停时间计算,display_score()始终基于pygame.time.get_ticks()实时时间减去start_time,导致时间仍在流逝。

修复步骤

1. 区分游戏启动与跳跃的SPACE按键

修改事件处理逻辑,仅在非游戏活跃状态下,按下SPACE才重置start_time并启动游戏,避免跳跃时误触发。

2. 暂停时冻结时间计算

新增pause_start_time变量记录暂停开始的时间,恢复游戏时将start_time补上暂停的时长,确保暂停期间时间不被计入分数。

修改后的完整代码

import pygame
from sys import exit
from random import randint, choice


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        player_walk_1 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/Player/player_walk_1.png').convert_alpha()
        player_walk_2 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/Player/player_walk_2.png').convert_alpha()
        self.player_walk = [player_walk_1, player_walk_2]
        self.player_index = 0
        self.player_jump = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/Player/jump.png').convert_alpha()

        self.image = self.player_walk[self.player_index]
        self.rect = self.image.get_rect(midbottom=(80, 300))
        self.gravity = 0

        self.jump_sound = pygame.mixer.Sound('C:/Users/user/Documents/Dragon_Runner/audio/jump.mp3')
        self.jump_sound.set_volume(0.5)

    def player_input(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and self.rect.bottom >= 300:
            self.gravity = -22
            self.jump_sound.play()

    def apply_gravity(self):
        self.gravity += 1
        self.rect.y += self.gravity
        if self.rect.bottom >= 300:
            self.rect.bottom = 300

    def animation(self):
        if self.rect.bottom < 300:
            self.image = self.player_jump
        else:
            self.player_index += 0.060
            if self.player_index >= len(self.player_walk): self.player_index = 0
            self.image = self.player_walk[int(self.player_index)]

    def update(self):
        self.player_input()
        self.apply_gravity()
        self.animation()


class Obstacle(pygame.sprite.Sprite):
    def __init__(self, type):
        super().__init__()

        if type == 'snail':
            snail_1 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/snail/snail1.png').convert_alpha()
            snail_2 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/snail/snail2.png').convert_alpha()
            self.frames = [snail_1, snail_2]
            y_pos = 300

        else:
            dragon_1 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/Green Dragon1.png').convert_alpha()
            dragon_2 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/Green Dragon2.png').convert_alpha()
            dragon_3 = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/Green Dragon3.png').convert_alpha()
            self.frames = [dragon_1, dragon_2, dragon_3]
            y_pos = 190

        self.animation_index = 0
        self.image = self.frames[self.animation_index]
        self.rect = self.image.get_rect(midbottom=(randint(900, 1100), y_pos))

    def animation(self):
        self.animation_index += 0.1
        if self.animation_index >= len(self.frames):
            self.animation_index = 0
        self.image = self.frames[int(self.animation_index)]

    def update(self):
        self.animation()
        self.rect.x -= 7
        self.destroy()

    def destroy(self):
        if self.rect.x <= -100:
            self.kill()


def display_score():
    global start_time, paused, pause_start_time
    if not paused:
        current_time = int(pygame.time.get_ticks() / 1000) - start_time
    else:
        # 暂停时显示当前分数,不更新时间
        current_time = score
    score_surf = font1.render(f'Score: {current_time}', False, 'black')
    score_rect = score_surf.get_rect(center=(400, 50))
    screen.blit(score_surf, score_rect)
    return current_time


def collision_sprite():
    if pygame.sprite.spritecollide(player.sprite, obstacle_group, False):
        obstacle_group.empty()
        return False
    else:
        return True


pygame.init()
screen = pygame.display.set_mode((800, 400))
pygame.display.set_caption('Dragon Runner')
clock = pygame.time.Clock()
font1 = pygame.font.Font('C:/Users/user/Documents/Dragon_Runner/font/Pixeltype.ttf', 50)
game_active = False
paused = False
start_time = 0
score = 0
pause_start_time = 0  # 新增:记录暂停开始时间
bg_music = pygame.mixer.Sound('C:/Users/user/Documents/Dragon_Runner/audio/music.wav')
bg_music.set_volume(0.2)
bg_music.play(loops=-1)

player = pygame.sprite.GroupSingle()
player.add(Player())

obstacle_group = pygame.sprite.Group()

sky_surface = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/Sky.png').convert()
ground_surface = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/ground.png').convert()

player_stand = pygame.image.load('C:/Users/user/Documents/Dragon_Runner/graphics/player/player_stand.png').convert_alpha()
player_stand = pygame.transform.rotozoom(player_stand, 0, 2)
player_stand_rect = player_stand.get_rect(center=(400, 200))

game_name = font1.render('Dragon Runner', False, (11, 196, 169))
game_name_rect = game_name.get_rect(center=(400, 80))

game_message = font1.render('Press space to run', False, (11, 196, 169))
game_message_rect = game_message.get_rect(center=(400, 330))

obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        # 仅在非游戏活跃状态下处理SPACE启动游戏
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and not game_active:
            game_active = True
            start_time = int(pygame.time.get_ticks() / 1000)

        if game_active and not paused:
            if event.type == obstacle_timer:
                obstacle_group.add(Obstacle(choice(['fly', 'snail', 'snail', 'snail'])))

            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                paused = True
                pause_start_time = int(pygame.time.get_ticks() / 1000)  # 记录暂停开始时间

        if paused:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_c:
                paused = False
                # 计算暂停时长,加到start_time上,抵消暂停的时间
                pause_duration = int(pygame.time.get_ticks() / 1000) - pause_start_time
                start_time += pause_duration

    if game_active and not paused:
        screen.blit(sky_surface, (0, 0))
        screen.blit(ground_surface, (0, 300))
        score = display_score()

        player.draw(screen)
        player.update()

        obstacle_group.draw(screen)
        obstacle_group.update()

        game_active = collision_sprite()

    if not game_active:
        screen.fill((94, 129, 162))
        screen.blit(player_stand, player_stand_rect)

        score_message = font1.render(f'Your score: {score}', False, (11, 196, 169))
        score_message_rect = score_message.get_rect(center = (400, 330))
        screen.blit(game_name, game_name_rect)

        if score == 0:
            screen.blit(game_message, game_message_rect)
        else:
            screen.blit(score_message, score_message_rect)

    if paused:
        screen.fill((94, 129, 162))
        screen.blit(player_stand, player_stand_rect)

        pause_message = font1.render('GAME PAUSED', False, (11, 196, 169))
        pause_message_rect = pause_message.get_rect(center = (400, 80))

        unpause_message = font1.render("Press 'c' to continue", False, (11, 196, 169))
        unpause_message_rect = unpause_message.get_rect(center = (400, 330))

        screen.blit(pause_message, pause_message_rect)
        screen.blit(unpause_message, unpause_message_rect)

    pygame.display.update()
    clock.tick(60)

关键修改说明

  • 事件处理优化:将SPACE启动游戏的逻辑限制在not game_active条件下,避免跳跃时误重置start_time。
  • 暂停时间冻结:新增pause_start_time记录暂停开始时刻,恢复时计算暂停时长并加到start_time中,确保分数计算跳过暂停阶段;同时修改display_score(),暂停时直接返回当前score值,不再实时计算时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:54:24