为了实现全屏显示,可以使用pygame.FULLSCREEN参数。由于全屏模式下的分辨率是未知的,我们需要在创建屏幕Surface后立即获取屏幕分辨率,并按比例计算显示尺寸。
我们设计成这样:初始窗口以两倍放大显示,当按下F12键时进入全屏模式,按下ESC键时退出全屏模式。修改后的完整代码如下所示:
05\03\Game.py
|
import pygame from constants import * from utils import * from Globals import * from Mario import Mario from TilesImageCache import TilesImageCache
class Game: def __init__(self): # 初始化 Pygame pygame.init()
# 先画到一个画布上 self.screen = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
# 真正的屏幕 self.window = pygame.display.set_mode((SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2), pygame.RESIZABLE) self.windowSize = self.window.get_rect().size
# 设置窗口标题 pygame.display.set_caption('super mario bros')
# 避免输入法影响按键 pygame.key.stop_text_input()
# 创建时钟对象 self.clock = pygame.time.Clock()
# 初始化图片缓存 Globals.tilesImageCache = TilesImageCache()
# 马里奥 self.mario = Mario(10, 100, self.screen)
# 地图数据 self.mapArray = [] self.mapViewFrom = 0 self.mapViewTo = SCREEN_WIDTH self.mapViewFromMax = 0
# 存储参与碰撞的物体信息 self.objectArray = []
# 初始化地图 self.initMap()
# 按比例计算画面尺寸 def resizeWindow(self, newSize): ratio = min(newSize[0] / SCREEN_WIDTH, newSize[1] / SCREEN_HEIGHT) newWidth = int(SCREEN_WIDTH * ratio) newHeight = int(SCREEN_HEIGHT * ratio) self.windowSize = (newWidth, newHeight)
# 初始化地图 def initMap(self):
# 地图数据 self.mapArray = loadMapData("1-1.txt")
# 滚动地图From的最大值 self.mapViewFromMax = len(self.mapArray[0]) * MAP_BLOCK_SIZE - SCREEN_WIDTH
# 存储参与碰撞的物体信息(地图坐标) for rowIndex in range(len(self.mapArray)): row = self.mapArray[rowIndex] for cellIndex in range(len(row)): cell = row[cellIndex] if cell == 1 or cell in Globals.tilesImageCache.bgImageList: continue # 背景图片,不碰撞 else: # 其他参与碰撞 posX = cellIndex * MAP_BLOCK_SIZE posY = rowIndex * MAP_BLOCK_SIZE self.objectArray.append(pygame.Rect(posX, posY, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE))
# 滚动地图 def scrollMap(self, step): self.mapViewFrom += step if self.mapViewFrom < 0: self.mapViewFrom = 0 if self.mapViewFrom > self.mapViewFromMax: self.mapViewFrom = self.mapViewFromMax self.mapViewTo = self.mapViewFrom + SCREEN_WIDTH
def drawMap(self): # 画地图 for rowIndex in range(len(self.mapArray)): row = self.mapArray[rowIndex] for cellIndex in range(len(row)): # 转换为屏幕坐标,在显示范围内才绘制,注意参数的顺序 screenPos = mapArrayToScreen(cellIndex, rowIndex) if screenPos[0] + MAP_BLOCK_SIZE > 0 and screenPos[0] < SCREEN_WIDTH: cell = row[cellIndex] # 编号在图片缓存中,则显示图片 if cell in Globals.tilesImageCache.imageMap: self.screen.blit(Globals.tilesImageCache.imageMap[cell], screenPos)
def run(self):
# 主循环 isRunning = True while isRunning: for event in pygame.event.get(): if event.type == pygame.QUIT: isRunning = False
# 按ESC退出全屏,变成窗口模式 # 按F12进入全屏模式 if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.window = pygame.display.set_mode((SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2), pygame.RESIZABLE) self.resizeWindow(self.window.get_rect().size) elif event.key == pygame.K_F12: self.window = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) self.resizeWindow(self.window.get_rect().size)
# 监测窗口大小变化事件 if event.type == pygame.VIDEORESIZE: self.resizeWindow((event.w, event.h))
# 全屏擦除(注意背景色改成了天蓝色) self.screen.fill(COLOR_SKY_BLUE)
# 绘制地图 self.drawMap()
# 获取按键状态 keys = pygame.key.get_pressed()
# 更新马里奥 self.mario.update(keys)
# 放大画面,显示在屏幕中间 print("size:" + str(self.windowSize)) newSurface = pygame.transform.scale(self.screen, self.windowSize) showPosX = (self.window.get_rect().size[0] - self.windowSize[0]) / 2 showPosY = (self.window.get_rect().size[1] - self.windowSize[1]) / 2 self.window.blit(newSurface, (showPosX, showPosY))
# 刷新显示 pygame.display.flip()
# 每秒60帧 self.clock.tick(60) # 退出 Pygame pygame.quit()
if __name__ == '__main__': game = Game() Globals.game = game # 保存起来,便于使用 game.run() |
运行程序,并尝试按下F12和ESC键进行显示模式切换吧。