如何修复Pygame暂停函数的两个异常:跳跃清零分数、暂停涨分
Pygame暂停功能的分数异常修复方案
问题现象
- 玩家跳跃时分数被清零
- 进入暂停界面后分数持续增长
问题根源
- 跳跃清零分数:全局事件处理中,所有SPACE按键都会触发
start_time重置,包括玩家跳跃时的SPACE输入,导致分数计算的时间基准被重新设置。 - 暂停时分数增长:暂停状态下没有暂停时间计算,
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
相关产品推荐
相关产品推荐

