为何Pygame使用set_at绘制的线条为4px宽而非1px?如何修复?
问题原因与解决方法
为什么线条显示为4px宽?
核心原因是系统高DPI缩放导致逻辑像素与物理像素不匹配:
- 你的电脑显示器开启了缩放(比如200%比例),但Pygame默认未适配高DPI机制,窗口的逻辑像素会被系统自动拉伸映射到物理像素上。你用
set_at绘制的1个逻辑像素,会被放大为4个物理像素(200%缩放的平方比例),因此工具检测到的是4px宽度。 - 你提到HTML Canvas也有同样问题,本质是一样的:Canvas默认也未开启高DPI适配,
fillRect(1,1)绘制的是逻辑像素,同样会被系统缩放拉伸。
修复方法
1. 开启Pygame高DPI适配
在初始化Pygame前设置环境变量,并使用SCALED标志创建窗口,让逻辑像素与物理像素正确对应:
import pygame import os # 开启高DPI支持 os.environ['SDL_VIDEO_ALLOW_HIGHDPI'] = '1' WHITE = (255, 255, 255) BLACK = (0, 0, 0) FPS = 10 pygame.init() # 使用SCALED标志,保持逻辑尺寸同时适配系统缩放 screen = pygame.display.set_mode((200, 200), pygame.SCALED) screen.fill(WHITE) # 绘制1px线条 for i in range(100): screen.set_at((i, 100), BLACK) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() pygame.display.update() pygame.time.Clock().tick(FPS)
2. 临时验证系统缩放
如果不想修改代码,可以临时把系统显示缩放调至100%:
- Windows:设置→系统→显示→缩放与布局→选择100%
- macOS:系统设置→显示器→缩放→选择“默认 for display”
此时运行代码,线条会显示为真正的1px宽,可直接验证问题根源。
3. 用pygame.draw.line替代(可选)
如果是绘制直线,直接用pygame.draw.line更高效,同样需在高DPI适配环境下使用:
# 替换循环绘制的代码,直接绘制1px线条 pygame.draw.line(screen, BLACK, (0, 100), (99, 100), width=1)
内容的提问来源于stack exchange,提问作者Vince M
相关产品推荐
相关产品推荐

