如何解决Pygame进度条指示器超出圆角边界的问题?
解决Pygame进度条圆角溢出问题
问题根源
Pygame里用pygame.draw.rect画的圆角矩形,根本不是标准正圆——它是用二次贝塞尔曲线拼出来的。你之前用正圆弧(pygame.draw.arc)做透明遮罩,路径对不上,自然会留溢出。
两种靠谱修复方案
方案1:用圆角蒙版裁剪(最简单)
先画一个带圆角的白色蒙版,把进度条内容和蒙版叠加,只保留蒙版范围内的部分,直接解决溢出问题:
import pygame # 假设你的进度条参数 bar_width, bar_height = 200, 40 border_radii = {"border_top_left_radius": 10, "border_top_right_radius": 10, "border_bottom_left_radius": 10, "border_bottom_right_radius": 10} progress_ratio = 0.7 # 进度0到1之间 # 创建带透明通道的进度条Surface progress_bar = pygame.Surface((bar_width, bar_height), pygame.SRCALPHA) # 画圆角蒙版:白色区域是要保留的部分 mask_surf = pygame.Surface((bar_width, bar_height), pygame.SRCALPHA) pygame.draw.rect(mask_surf, (255,255,255), (0,0,bar_width,bar_height), border_radius=list(border_radii.values())) # 先画进度条底色和进度内容 pygame.draw.rect(progress_bar, (200,200,200), (0,0,bar_width,bar_height), border_radius=list(border_radii.values())) pygame.draw.rect(progress_bar, (0,150,255), (0,0,int(bar_width*progress_ratio), bar_height)) # 叠加蒙版:只保留蒙版白色区域的内容 progress_bar.blit(mask_surf, (0,0), special_flags=pygame.BLEND_RGBA_MULT)
方案2:手动拆分绘制进度条
不想用蒙版的话,就把进度条拆成圆角部分和矩形部分分开画,精准控制每个区域的内容:
import pygame import math bar_width, bar_height = 200, 40 border_radii = {"border_top_left_radius": 10, "border_top_right_radius": 10, "border_bottom_left_radius": 10, "border_bottom_right_radius": 10} progress_ratio = 0.7 progress_width = int(bar_width * progress_ratio) progress_bar = pygame.Surface((bar_width, bar_height), pygame.SRCALPHA) # 先画底色圆角矩形 pygame.draw.rect(progress_bar, (200,200,200), (0,0,bar_width,bar_height), border_radius=list(border_radii.values())) left_r = border_radii["border_top_left_radius"] right_r = border_radii["border_top_right_radius"] # 处理左侧进度 if progress_width >= left_r: # 进度覆盖左侧圆角:画两个半圆+中间矩形 pygame.draw.circle(progress_bar, (0,150,255), (left_r, left_r), left_r) pygame.draw.circle(progress_bar, (0,150,255), (left_r, bar_height-left_r), left_r) pygame.draw.rect(progress_bar, (0,150,255), (left_r, 0, progress_width - left_r, bar_height)) else: # 进度没覆盖左侧圆角:画扇形+小矩形 angle = math.degrees(math.acos((left_r - progress_width)/left_r)) # 上半部分扇形 pygame.draw.arc(progress_bar, (0,150,255), (0,0,left_r*2, left_r*2), math.radians(90+angle), math.radians(270-angle), left_r) # 下半部分扇形 pygame.draw.arc(progress_bar, (0,150,255), (0, bar_height-left_r*2, left_r*2, left_r*2), math.radians(270+angle), math.radians(90-angle), left_r) # 连接扇形的矩形 pygame.draw.rect(progress_bar, (0,150,255), (progress_width, 0, left_r - progress_width, bar_height)) # 处理右侧进度 if progress_width > bar_width - right_r: # 进度覆盖右侧圆角:画两个半圆 pygame.draw.circle(progress_bar, (0,150,255), (bar_width-right_r, right_r), right_r) pygame.draw.circle(progress_bar, (0,150,255), (bar_width-right_r, bar_height-right_r), right_r)
重点提醒
别再纠结用正圆弧遮罩了,Pygame的圆角矩形是贝塞尔曲线,和正圆路径天生不一样,怎么调参数都没法完美匹配。蒙版法是最省心的,推荐优先用。
内容的提问来源于stack exchange,提问作者Becse
相关产品推荐
相关产品推荐

