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

Pygame Surface缩放异常:缩小带网格Surface后线条显示错误

问题

在Pygame中绘制带网格的Surface时,原显示正常,但缩小尺寸后出现线条绘制异常的bug。原本以为在指定尺寸的虚拟Surface上绘制内容后,缩放时内部所有元素会同步缩放,但实际并非如此。

代码如下:

import pygame
WIDTH = 640
HEIGHT = 320
TILE_SIZE = 32

pygame.init()

# 16:9 比例
screen = pygame.display.set_mode((192, 108), pygame.RESIZABLE)
s = pygame.Surface([WIDTH, HEIGHT])

pygame.display.set_caption("Grid")

def draw_grid():
    s.fill((255, 255, 255))
    for v in range((WIDTH // TILE_SIZE) + 1):
        # 垂直线
        pygame.draw.line(s, (0, 0, 0), (TILE_SIZE * v, 0), (TILE_SIZE * v, HEIGHT))
    # 水平线
    for h in range((HEIGHT // TILE_SIZE) + 1):
        pygame.draw.line(s, (0, 0, 0), (0, TILE_SIZE * h), (WIDTH, TILE_SIZE * h))

def draw_bg():
    temp_frame = pygame.transform.scale(s, (192, 108)) # 此处出现bug
    screen.blit(temp_frame , (0, 0))

    # screen.blit(s, (0, 0)) 可以正常显示

while True:
    draw_grid()
    draw_bg()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    pygame.display.flip()

尝试修改draw_grid函数中的WIDTH和HEIGHT变量,但问题未解决。

解决方案

这个问题源于pygame.transform.scale默认的缩放算法会让细线条在非整数倍缩小后丢失或变形,以下是几种可行的解决方法:

方法1:使用平滑缩放替代普通缩放

用pygame.transform.smoothscale替换scale,它的算法会更好地保留线条细节,修改draw_bg函数:

def draw_bg():
    temp_frame = pygame.transform.smoothscale(s, (192, 108))
    screen.blit(temp_frame , (0, 0))

方法2:直接在目标尺寸上绘制网格

跳过缩放步骤,直接根据屏幕尺寸计算网格参数,在最终显示的Surface(或screen)上绘制,从根源避免缩放失真。修改后的完整代码:

import pygame
SCREEN_WIDTH = 192
SCREEN_HEIGHT = 108
ORIG_TILE_SIZE = 32
ORIG_WIDTH = 640
ORIG_HEIGHT = 320

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.RESIZABLE)
pygame.display.set_caption("Grid")

def draw_grid():
    screen.fill((255, 255, 255))
    # 计算适配屏幕的网格单元尺寸
    scaled_tile_w = SCREEN_WIDTH / (ORIG_WIDTH // ORIG_TILE_SIZE)
    scaled_tile_h = SCREEN_HEIGHT / (ORIG_HEIGHT // ORIG_TILE_SIZE)
    
    # 绘制垂直线
    for v in range(int(ORIG_WIDTH // ORIG_TILE_SIZE) + 1):
        pygame.draw.line(screen, (0, 0, 0), (scaled_tile_w * v, 0), (scaled_tile_w * v, SCREEN_HEIGHT))
    # 绘制水平线
    for h in range(int(ORIG_HEIGHT // ORIG_TILE_SIZE) + 1):
        pygame.draw.line(screen, (0, 0, 0), (0, scaled_tile_h * h), (SCREEN_WIDTH, scaled_tile_h * h))

while True:
    draw_grid()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        # 窗口 resize 时更新尺寸
        if event.type == pygame.VIDEORESIZE:
            SCREEN_WIDTH, SCREEN_HEIGHT = event.size
            screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.RESIZABLE)

    pygame.display.flip()

方法3:加粗原始线条

在绘制原始网格时给线条增加宽度,让缩放后线条不容易消失,修改draw_grid中的画线代码:

pygame.draw.line(s, (0, 0, 0), (TILE_SIZE * v, 0), (TILE_SIZE * v, HEIGHT), width=2)
pygame.draw.line(s, (0, 0, 0), (0, TILE_SIZE * h), (WIDTH, TILE_SIZE * h), width=2)

内容的提问来源于stack exchange,提问作者r'ouster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:26:07