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

如何解决Pygame开发井字棋时文本重叠、背景被覆盖的问题

问题根因

你的代码将所有静态元素(棋盘网格、功能按钮、分割线)的绘制逻辑放在了主循环外,仅在程序初始化时绘制一次。因此你调用全局screen.fill(bg_color)清除旧文本时会把所有静态元素一并覆盖,不做清除的话新文本直接叠加在旧文本上就会出现重叠。

解决方案

这里提供两种修改方案,你可以根据需求选择:

方案1:局部擦除(改动最小)

仅清除分数文本所在的小范围区域,不需要重绘所有静态元素,修改步骤如下:

  1. 删掉x_button点击事件里的全局screen.fill(bg_color)代码
  2. 在show_score()函数里渲染新分数前,先用背景色填充分数所在的矩形区域,覆盖旧的分数文本

修改后的show_score()代码如下:

def show_score(x_str, bg_color):
    # 先擦除旧分数:按文本大概尺寸填充背景色,可根据实际显示效果调整宽高
    score_x = (screen_width / 2)+210
    score_y = (screen_height / 2) +160
    pygame.draw.rect(screen, bg_color, (score_x, score_y, 30, 24))
    # 再绘制新分数
    img = font.render(str(x_str), True, (214, 55, 47))
    screen.blit(img, (score_x, score_y))

同时需要把主循环里点击事件的screen.fill(bg_color)删掉,调用show_score的时候把bg_color传进去即可:

if x_button.collidepoint(mouse_pos):
    clicker ="x"
    txt +=1
    # 删掉原来的screen.fill(bg_color)
    show_score(txt, bg_color)
    print('button was pressed at {0}'.format(mouse_pos))

方案2:逐帧全量重绘(更规范,适合后续功能扩展)

Pygame的标准渲染逻辑是每帧清空全屏后重绘所有元素,这种方式后续新增元素不需要单独处理擦除逻辑,稳定性更高:

  1. 把所有静态元素的绘制逻辑封装成独立函数
  2. 在主循环里每帧先清空全屏,再调用绘制函数,最后绘制动态的分数文本

核心修改示例:

# 新增全局绘制函数
def draw_all(x_button, o_button, s_button, board_buttons, bg_color, light_grey, light_grey2, green):
    screen.fill(bg_color)
    # 绘制所有按钮
    pygame.draw.rect(screen, light_grey, x_button)
    pygame.draw.rect(screen, light_grey, o_button)
    for btn in board_buttons:
        pygame.draw.rect(screen, light_grey, btn)
    pygame.draw.rect(screen, green, s_button)
    # 绘制分割线
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) +175,0),((screen_width/2)+175,screen_height))
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) +75,0),((screen_width/2)+75,screen_height))
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) -25,0),((screen_width/2)-25,screen_height))
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) -125,0),((screen_width/2)-125,screen_height))
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) -125,(screen_height/3)),((screen_width/2)+175,(screen_height/3)))
    pygame.draw.aaline(screen,light_grey2, ((screen_width/2) -125,(screen_height/3)*2 ),((screen_width/2)+175,(screen_height/3)*2))
    # 绘制固定文本
    img2 = font.render('O', True, (214, 55, 47))
    screen.blit(img2, ((screen_width / 2) + 260, (screen_height / 2) + 160))

# 主循环修改为
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = event.pos
            if x_button.collidepoint(mouse_pos):
                clicker ="x"
                txt +=1
                print('button was pressed at {0}'.format(mouse_pos))
            elif o_button.collidepoint(mouse_pos):
                clicker = "o"
    # 每帧全量重绘
    draw_all(x_button, o_button, s_button, [one_one,one_two,one_three,two_one,two_two,two_three,three_one,three_two,three_three], bg_color, light_grey, light_grey2, green)
    show_score(txt)
    pygame.display.flip()
    clock.tick(60)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:48:04