因此,在我看过的每个Pygame例子中,似乎都有一个解决方案,游戏设计用于播放,就是这样。没有用于设置更高或更低分辨率的选项。如果您确实通过display.set_mode更改了分辨率,那么游戏纹理/图形的比例就会变得严重,游戏就会无法播放。
在我看过的所有例子中,看起来你必须为每个目标分辨率实际创建不同大小的纹理集......这看起来很荒谬。这引出了我的问题。
如果我基于480x270的标准分辨率设计游戏,是否可以简单地将该表面的输出缩放到1080p(或1440p,4k等),同时仍然使用为480x270构建的游戏资产?如果是这样,任何人都可以发布一个如何实现这一目标的例子吗?任何提示或指示也将不胜感激。
您可以在设计分辨率下制作虚拟表面,并将其缩放到游戏运行的分辨率:
window = pygame.set_mode([user_x, user_y])
w = pygame.Surface([design_x, design_y])
def draw():
frame = pygame.transform.scale(w, (user_x, user_y))
window.blit(frame, frame.get_rect())
pygame.display.flip()
在虚拟表面上绘制所有内容,它将缩放到屏幕上。这需要固定的屏幕高度与屏幕宽度比。
花了一些时间修补并组装了一个演示如何解决这个问题的演示。找到一个用于测试的图像,并将脚本中的字符串路径放入脚本中以获取imagePath的值。
该脚本的功能很简单。当您在箭头键上向左或向右按时,屏幕分辨率会循环显示可接受分辨率的元组,并且屏幕会相应调整大小,同时将测试图像缩放到新分辨率。
import pygame,sys
from pygame import *
from pygame.locals import *
displayIndex = 0
pygame.init()
##standard 16:9 display ratios
DISPLAYS = [(1024,576),(1152,648),(1280,720),(1600,900),(1920,1080),(2560,1440)]
screen = pygame.display.set_mode(DISPLAYS[displayIndex])
screen.fill((0,0,0))
### change image path to a string that names an image you'd like to load for testing. I just used a smiley face from google image search.
### Put it in the same place as this file or set up your paths appropriately
imagePath = "Smiley-icon.png"
class Icon(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.smileyImage = pygame.image.load(imagePath)
self.image = self.smileyImage.convert_alpha()
### need to assume a default scale, DISPLAYS[0] will be default for us
self.rect = self.image.get_rect()
self.posX = x
self.posY = y
self.rect.x = x
self.rect.y = y
self.defaultx = (float(self.rect[2])/DISPLAYS[0][0])*100
self.defaulty = (float(self.rect[3])/DISPLAYS[0][1])*100
## this is the percent of the screen that the image should take up in the x and y planes
def updateSize(self,):
self.image = ImageRescaler(self.smileyImage,(self.defaultx,self.defaulty))
self.rect = self.image.get_rect()
self.rect.x = self.posX
self.rect.y = self.posY
def ImageRescaler(image,originalScaleTuple): #be sure to restrict to only proper ratios
newImage = pygame.transform.scale(image,(int(DISPLAYS[displayIndex][0]*(originalScaleTuple[0]/100)),
int(DISPLAYS[displayIndex][1]*(originalScaleTuple[1]/100))))
return newImage
def resizeDisplay():
screen = pygame.display.set_mode(DISPLAYS[displayIndex])
## this is where you'd have'd probably want your sprite groups set to resize themselves
## Just gonna call it on icon here
icon.updateSize()
icon = Icon(100,100)
while True:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT:
displayIndex -=1
if displayIndex < 0:
displayIndex = 5
resizeDisplay()
elif event.key == K_RIGHT:
displayIndex+=1
if displayIndex > 5:
displayIndex = 0
resizeDisplay()
screen.blit(icon.image,(icon.rect.x,icon.rect.y))
pygame.display.update()
解决这个问题的最佳方法是缩小图像尺寸,以保持图像质量。这有两个选择:
这种方法可能是最快的。
screen = pygame.display.set_mode((user_x, user_y))
image = pygame.image.load("a.png").convert_alpha()
pygame.transform.scale(image, (screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=image)
screen = pygame.display.set_mode((user_x, user_y))
surface = pygame.Surface((1920, 1080))
surface.blit(image, rect)
# Etc...
pygame.transform.scale(surface, ((screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=surface)
screen.blit(surface, (0, 0))
pygame.display.update()
此过程(缩小)允许您保留图像质量,同时仍允许用户选择其屏幕分辨率。因为你经常操纵图像会慢一些。