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

如何在Pygame记忆配对游戏中显示玩家最终用时?

解决记忆配对游戏的计时器持续运行与最终用时显示问题

我帮你排查了代码,发现两个核心问题导致计时器停不下来,而且没法正确获取最终用时:一是时间计算的公式写错了,二是游戏结束后没有冻结计时并保存最终时间值。下面一步步给你修正:

问题1:时间计算逻辑错误

你当前的时间计算是:

time = 0 + int((pygame.time.get_ticks() + start_time) / 1000)

这里应该用当前时间减去初始时间,因为pygame.time.get_ticks()返回的是从pygame初始化到现在的毫秒数,所以正确的公式是:

time = int((pygame.time.get_ticks() - start_time) / 1000)

问题2:游戏结束后未停止计时并保存最终用时

当matches达到15(也就是全部配对完成)时,你设置了game_over = True,但后续的循环里依然会调用draw_backgrounds()更新时间,而且end_time变量完全没定义,导致显示时会报错。

修改方案:

  1. 在游戏结束时,立即保存当前的time作为end_time,之后不再更新time变量。
  2. 修复draw_backgrounds()里的时间更新逻辑,只有在game_over为False时才计算时间。
  3. 确保游戏结束界面显示的是正确的end_time。

修改后的关键代码部分

1. 修正draw_backgrounds()函数:

def draw_backgrounds():
    global start_time, time, end_time
    
    top_menu = pygame.draw.rect(screen, orange, [0, 0, screen_width, 75])
    score_text = small_font.render(f'Player 1 score :  {score}', True, white)
    screen.blit(score_text, (20, 20))
    
    board_space = pygame.draw.rect(screen, turquoise, [0, 100, screen_width, screen_height - 200], 0)
    
    bottom_menu = pygame.draw.rect(screen, orange, [0, screen_height - 100, screen_width, 100], 0)
    # 只有游戏未结束时才更新时间
    if not game_over:
        time = int((pygame.time.get_ticks() - start_time) / 1000)
        time_text = small_font.render(f'Your time: {time}', True, white)
        screen.blit(time_text, (20, 550))
    else:
        # 游戏结束后显示最终用时
        time_text = small_font.render(f'Final Time: {end_time}', True, white)
        screen.blit(time_text, (20, 550))

2. 修正游戏结束的判断逻辑:

#Checks for game over
if matches == rows * cols // 2 and not game_over:
    game_over = True
    end_time = time  # 保存最终用时
    winner = pygame.draw.rect(screen, turquoise,[0, 0, 600, 600])
    winner_text = large_font.render(f'YOUR TIME WAS {end_time} !!', True, orange)
    screen.blit(winner_text, (70, screen_height - 350))

这里加了and not game_over的判断,避免每次循环都重复创建结束界面和赋值end_time。

3. 初始化end_time变量

在游戏变量定义部分添加:

end_time = 0

完整修改后的代码(关键部分已修正)

# build a guessing game!
import random
import pygame


global options_list, spaces, used, new_board, first_guess, second_guess, first_guess_num, second_guess_num, score, matches, game_over, rows, cols, correct, time, end_time
pygame.init()

# game variables and constants
screen_width = 600
screen_height = 600
white = (255, 255, 255)
black = (0, 0, 0)
orange = (255,97,3)
turquoise = (0, 206, 209)
green = (0, 255, 0)
fps = 60
timer = pygame.time.Clock()
rows = 5
cols = 6
correct = [[0, 0, 0, 0, 0, 0,],
           [0, 0, 0, 0, 0, 0,], 
           [0, 0, 0, 0, 0, 0,],
           [0, 0, 0, 0, 0, 0,],
           [0, 0, 0, 0, 0, 0]]

options_list = []
spaces = []
used = []
new_board = True
first_guess = False
second_guess = False
#Guess is assigned an index value. Checks what number is clicked
first_guess_num = 0
second_guess_num = 0
score = 0
matches = 0
game_over = False
cards_left_covered = 0
#timer start time
start_time = pygame.time.get_ticks()
time = 0
end_time = 0  # 新增最终用时变量

# create screen
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption('Memory Game!')
#sets fonts
large_font = pygame.font.Font('freesansbold.ttf', 56)
small_font = pygame.font.Font('freesansbold.ttf', 26)



def generate_board():
    global options_list, spaces, used
    for item in range(rows * cols // 2):
        options_list.append(item)
        
# goes through list of options between 1-24. Guarantees that only 2 cards can be selected
    for item in range(rows * cols):
        card = options_list[random.randint(0, len(options_list) - 1)]
        spaces.append(card)
        if card in used:
            used.remove(card)
            options_list.remove(card)
        else:
            used.append(card)

#Sets background colours and shapes
def draw_backgrounds():
    global start_time, time, end_time
    
    top_menu = pygame.draw.rect(screen, orange, [0, 0, screen_width, 75])
    score_text = small_font.render(f'Player 1 score :  {score}', True, white)
    screen.blit(score_text, (20, 20))
    
    board_space = pygame.draw.rect(screen, turquoise, [0, 100, screen_width, screen_height - 200], 0)
    
    bottom_menu = pygame.draw.rect(screen, orange, [0, screen_height - 100, screen_width, 100], 0)
    # 游戏未结束时才更新时间
    if not game_over:
        time = int((pygame.time.get_ticks() - start_time) / 1000)
        time_text = small_font.render(f'Your time: {time}', True, white)
        screen.blit(time_text, (20, 550))
    else:
        # 游戏结束后显示最终用时
        time_text = small_font.render(f'Final Time: {end_time}', True, white)
        screen.blit(time_text, (20, 550))
    
    


def draw_cards():
    global rows, columns, correct
    card_list = []
    for i in range(cols):
        for j in range(rows):
            
            #draws the cards and sets their size and position
            card = pygame.draw.rect(screen, orange,[i * 85 + 48, j *78 + 110, 61, 65], 0, 4)
            card_list.append(card)
            ## randomly adds numbers onto the cards. to make sure that the black numbers dont populate instantly when game is created 
            '''card_text = small_font.render(f'{spaces[i * rows + j]}', True, black)
            screen.blit(card_text, (i * 75 + 18, j * 65 + 120))'''

    for r in range(rows):
        for c in range(cols):
            if correct[r][c] == 1:
                #creates green border around cards when match is made
                pygame.draw.rect(screen, green, [c * 85 + 48, r * 78 + 110, 61, 65], 3, 4)
                card_text = small_font.render(f'{spaces[c * rows + r]}', True, black)
                screen.blit(card_text, (c * 85 + 55, r * 78 + 125))

    return card_list


def check_guesses(first, second):
    global spaces, correct, score, matches
    if spaces[first] == spaces[second]:
        
        #floor division
        col1 = first // rows
        col2 = second // rows
        row1 = first - (first // rows * rows)
        row2 = second - (second // rows * rows)

        #checks for match and score incremented by 1
        if correct[row1][col1] == 0 and correct[row2][col2] == 0:
            correct[row1][col1] = 1
            correct[row2][col2] = 1
            score += 1
            matches += 1


running = True
while running:
    timer.tick(fps)
    screen.fill(turquoise)
    if new_board:
        generate_board()
        new_board = False

    draw_backgrounds()
    board = draw_cards()

    if first_guess and second_guess:
        check_guesses(first_guess_num, second_guess_num)
        
        ##delays code for miliseconds to see second guess
        pygame.time.delay(1000)
        first_guess = False
        second_guess = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            for i in range(len(board)):
                button = board[i]
                
            #can guess as long as it's not game over
                if not game_over:
                 if button.collidepoint(event.pos) and not first_guess:
                    first_guess = True
                    first_guess_num = i
                    
        ##ensures that the same card cannot be clicked twice
                if button.collidepoint(event.pos) and not second_guess and first_guess and i != first_guess_num:
                    second_guess = True
                    second_guess_num = i
                    

#Checks for game over
    if matches == rows * cols // 2 and not game_over:
        game_over = True
        end_time = time  # 保存最终用时
        winner = pygame.draw.rect(screen, turquoise,[0, 0, 600, 600])
        winner_text = large_font.render(f'YOUR TIME WAS {end_time} !!', True, orange)
        screen.blit(winner_text, (70, screen_height - 350))
        

#allows card to be flipped to show number
    if first_guess:
        card_text = small_font.render(f'{spaces[first_guess_num]}', True, black)
        location = (first_guess_num // rows * 85 + 55, (first_guess_num - (first_guess_num // rows * rows)) * 78 + 125)
        screen.blit(card_text, (location))
        
    if second_guess:
        card_text = small_font.render(f'{spaces[second_guess_num]}', True, black)
        location = (second_guess_num // rows * 85 + 55, (second_guess_num - (second_guess_num // rows * rows)) * 78 + 125)
        screen.blit(card_text, (location))

    pygame.display.flip()
pygame.quit()

现在这样修改后,游戏结束时计时器会停止,并且正确显示最终用时了。核心就是在游戏结束时冻结时间,并且修正时间计算的公式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:10:47