如何解决Pygame开发井字棋时文本重叠、背景被覆盖的问题
问题根因
你的代码将所有静态元素(棋盘网格、功能按钮、分割线)的绘制逻辑放在了主循环外,仅在程序初始化时绘制一次。因此你调用全局screen.fill(bg_color)清除旧文本时会把所有静态元素一并覆盖,不做清除的话新文本直接叠加在旧文本上就会出现重叠。
解决方案
这里提供两种修改方案,你可以根据需求选择:
方案1:局部擦除(改动最小)
仅清除分数文本所在的小范围区域,不需要重绘所有静态元素,修改步骤如下:
- 删掉
x_button点击事件里的全局screen.fill(bg_color)代码 - 在
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的标准渲染逻辑是每帧清空全屏后重绘所有元素,这种方式后续新增元素不需要单独处理擦除逻辑,稳定性更高:
- 把所有静态元素的绘制逻辑封装成独立函数
- 在主循环里每帧先清空全屏,再调用绘制函数,最后绘制动态的分数文本
核心修改示例:
# 新增全局绘制函数 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
相关产品推荐
相关产品推荐

