如何在Pygame中实现窗口持续缩小且避免闪烁异常?
Pygame实现窗口持续缩小效果的正确方式
你的代码问题出在每帧都调用pygame.display.set_mode()——这个函数是用来创建或切换显示模式的,频繁调用会导致系统反复重建窗口,进而引发闪烁、尺寸异常等不稳定问题。另外,你计算的窗口尺寸可能是浮点数,而窗口的宽高必须是整数,这也会导致尺寸异常。
下面提供两种可靠的实现方式:
方案一:固定窗口,内部缩放渲染内容(推荐)
这种方式不改变实际窗口大小,而是将所有游戏内容绘制在一个原始分辨率的Surface上,再通过缩放这个Surface来模拟窗口缩小的效果,完全不会出现闪烁问题,体验更流畅。
import pygame import sys # 原始游戏分辨率 ORIGINAL_WIDTH = 1600 ORIGINAL_HEIGHT = 900 # 初始缩放比例 scale = 0.8 # 窗口固定大小(可以和原始分辨率一致,也可以自定义) WINDOW_WIDTH = int(ORIGINAL_WIDTH * scale) WINDOW_HEIGHT = int(ORIGINAL_HEIGHT * scale) background_color = (255, 255, 255) pygame.init() # 创建固定大小的窗口 screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) # 创建原始分辨率的Surface,所有游戏内容都绘制在这里 game_surface = pygame.Surface((ORIGINAL_WIDTH, ORIGINAL_HEIGHT)) clock = pygame.time.Clock() running = True while running: # 1. 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 2. 更新缩放比例(控制缩小速度) scale -= 0.0005 # 限制最小缩放比例,避免内容太小 if scale < 0.2: scale = 0.2 # 3. 在原始Surface上绘制游戏内容 game_surface.fill(background_color) # 这里可以添加你的游戏元素绘制代码,比如玩家、敌人等 # 示例:绘制一个红色矩形模拟玩家 pygame.draw.rect(game_surface, (255, 0, 0), (ORIGINAL_WIDTH//2 - 25, ORIGINAL_HEIGHT//2 - 25, 50, 50)) # 4. 将原始Surface缩放到当前比例,再绘制到窗口 scaled_surface = pygame.transform.scale(game_surface, (int(ORIGINAL_WIDTH * scale), int(ORIGINAL_HEIGHT * scale))) # 居中显示缩放后的内容 screen.fill((0, 0, 0)) # 窗口背景填黑色,突出缩小的游戏区域 screen.blit(scaled_surface, ((WINDOW_WIDTH - scaled_surface.get_width())//2, (WINDOW_HEIGHT - scaled_surface.get_height())//2)) # 5. 更新显示 pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()
方案二:合理调整窗口实际大小(适合必须真改变窗口的场景)
如果一定要让窗口本身持续缩小,需要避免每帧调用set_mode(),同时确保尺寸为整数,并且控制调整频率:
import pygame import sys ORIGINAL_WIDTH = 1600 ORIGINAL_HEIGHT = 900 scale = 0.8 # 记录上一次调整窗口的帧数,避免每帧都调整 last_resize_frame = 0 resize_interval = 2 # 每2帧调整一次窗口大小 background_color = (255, 255, 255) pygame.init() # 初始窗口 screen = pygame.display.set_mode((int(ORIGINAL_WIDTH * scale), int(ORIGINAL_HEIGHT * scale))) clock = pygame.time.Clock() running = True frame_count = 0 while running: frame_count += 1 # 1. 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 2. 每隔指定帧数调整一次窗口大小 if frame_count - last_resize_frame >= resize_interval: scale -= 0.001 # 因为调整频率降低,这里可以加快缩小速度 if scale < 0.2: scale = 0.2 # 确保尺寸是整数 new_width = int(ORIGINAL_WIDTH * scale) new_height = int(ORIGINAL_HEIGHT * scale) # 重新设置窗口模式 screen = pygame.display.set_mode((new_width, new_height)) last_resize_frame = frame_count # 3. 绘制内容 screen.fill(background_color) # 示例绘制玩家 pygame.draw.rect(screen, (255, 0, 0), (new_width//2 - 25, new_height//2 - 25, 50, 50)) pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()
关键注意点
- 无论哪种方式,都要确保窗口尺寸为整数,避免浮点数导致的异常。
- 方案一的缩放方式更稳定,不会破坏窗口的交互逻辑,推荐优先使用。
- 可以根据游戏节奏调整缩小的速度,避免玩家体验过差。
内容的提问来源于stack exchange,提问作者DiamondCat64
相关产品推荐
相关产品推荐

