如何实现Pygame窗口仅在非游戏活跃状态下可调整大小
Pygame窗口可调整状态动态切换与固定分辨率方案
一、动态切换窗口可调整状态
要实现游戏活跃(self.stats.game_active=True)时窗口不可调整、非活跃时可调整的效果,核心是通过pygame.display.set_mode()动态修改窗口的flags参数,同时跟踪当前状态避免重复调用。
步骤与代码修改
- 初始化时添加状态跟踪
在主类的__init__方法里,新增变量记录当前窗口是否可调整:
def __init__(self): """Initialize the game, and create game resources.""" pygame.init() self.clock = pygame.time.Clock() self.settings = Settings() # 标记当前窗口是否可调整,初始为True(非活跃状态) self.screen_resizable = True self.screen = pygame.display.set_mode((1250, 660), pygame.RESIZABLE) self.settings.screen_width = self.screen.get_rect().width self.settings.screen_height = self.screen.get_rect().height
- 在游戏循环中检查并切换状态
在run_game的循环内,每次迭代检查game_active的状态,和当前窗口可调整状态对比,不一致则更新窗口:
def run_game(self): """Main loop for the game.""" running = True i = 0 while running: if not self.paused: # check if the game is paused # 计算期望的可调整状态:游戏非活跃时允许调整 desired_resizable = not self.stats.game_active if desired_resizable != self.screen_resizable: self.screen_resizable = desired_resizable # 获取当前窗口尺寸 current_size = (self.settings.screen_width, self.settings.screen_height) # 设置对应flags:允许调整则加RESIZABLE,否则用普通窗口flags flags = pygame.RESIZABLE if desired_resizable else pygame.HWSURFACE | pygame.DOUBLEBUF self.screen = pygame.display.set_mode(current_size, flags) # 更新设置中的分辨率参数 self.settings.screen_width = self.screen.get_rect().width self.settings.screen_height = self.screen.get_rect().height # 原背景切换逻辑 if self.stats.level <= 1: self.bg_img = self.reset_bg elif self.stats.level == 4: self.bg_img = self.second_bg elif self.stats.level >= 6: self.bg_img = self.third_bg self.screen.blit(self.bg_img, [0,i]) self.screen.blit(self.bg_img, [0, i - self.settings.screen_height]) if i >= self.settings.screen_height: i = 0 i += 1 self.check_events() self._check_game_over() # 原游戏活跃时的逻辑 if self.stats.game_active: if self.stats.level >= 7: self._create_asteroids() self._update_asteroids() self._check_asteroids_collisions() self._create_power_ups() self._update_power_ups() self._create_alien_bullets(3) self._update_alien_bullets() self._check_alien_bullets_collisions() self._check_power_ups_collisions() self._update_bullets() self._update_aliens() self.first_player_ship.update() self.second_player_ship.update() self._shield_collisions(self.ships, self.aliens, self.alien_bullet, self.asteroids) self._update_screen() self.clock.tick(60) self._check_for_pause()
- 处理窗口调整事件
在check_events方法中监听VIDEORESIZE事件,仅当窗口可调整时更新分辨率:
def check_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: # 这里添加退出游戏的逻辑,比如设置running=False pass elif event.type == pygame.VIDEORESIZE and self.screen_resizable: # 更新分辨率设置并重建窗口 self.settings.screen_width = event.w self.settings.screen_height = event.h self.screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE) # 可选:添加背景、游戏元素的适配逻辑,比如缩放背景图
二、固定分辨率选择方案
如果不想让玩家自由拉伸窗口,可提供预设分辨率列表,让玩家在游戏非活跃状态(比如主菜单)选择:
实现思路
- 定义分辨率列表
在主类或Settings类中预设可选分辨率:
# 示例分辨率列表,可根据需求修改 self.available_resolutions = [(1024, 768), (1280, 720), (1920, 1080)] self.current_resolution = (1250, 660) # 默认分辨率
- 添加分辨率选择界面
在游戏非活跃状态(比如主菜单)添加交互元素(按钮、菜单选项),玩家选择后调用以下方法更新窗口:
def set_resolution(self, resolution): self.current_resolution = resolution # 创建固定尺寸窗口,不可调整 self.screen = pygame.display.set_mode(resolution, pygame.HWSURFACE | pygame.DOUBLEBUF) self.settings.screen_width = resolution[0] self.settings.screen_height = resolution[1] # 必须添加:适配游戏内所有元素,比如缩放背景图、调整精灵位置和大小
- 状态锁定
游戏活跃时保持窗口固定不可调整,仅在非活跃状态允许切换分辨率。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

