如何使用Pygame将设计分辨率缩放到其他分辨率?

问题描述 投票:4回答:3

因此,在我看过的每个Pygame例子中,似乎都有一个解决方案,游戏设计用于播放,就是这样。没有用于设置更高或更低分辨率的选项。如果您确实通过display.set_mode更改了分辨率,那么游戏纹理/图形的比例就会变得严重,游戏就会无法播放。

在我看过的所有例子中,看起来你必须为每个目标分辨率实际创建不同大小的纹理集......这看起来很荒谬。这引出了我的问题。

如果我基于480x270的标准分辨率设计游戏,是否可以简单地将该表面的输出缩放到1080p(或1440p,4k等),同时仍然使用为480x270构建的游戏资产?如果是这样,任何人都可以发布一个如何实现这一目标的例子吗?任何提示或指示也将不胜感激。

python pygame game-engine
3个回答
1
投票

您可以在设计分辨率下制作虚拟表面,并将其缩放到游戏运行的分辨率:

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()

在虚拟表面上绘制所有内容,它将缩放到屏幕上。这需要固定的屏幕高度与屏幕宽度比。


2
投票

花了一些时间修补并组装了一个演示如何解决这个问题的演示。找到一个用于测试的图像,并将脚本中的字符串路径放入脚本中以获取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()

2
投票

解决这个问题的最佳方法是缩小图像尺寸,以保持图像质量。这有两个选择:

选项1

这种方法可能是最快的。

  1. 创建图像以与您打算支持的最大分辨率兼容。
  2. 使用用户所需的大小创建一个屏幕。 screen = pygame.display.set_mode((user_x, user_y))
  3. 在加载时缩小图像 image = pygame.image.load("a.png").convert_alpha() pygame.transform.scale(image, (screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=image)
  4. 现在,只是正常地将它们搞砸。它应该以正常速度运行。

选项2

  1. 使用用户所需的大小创建一个屏幕。 screen = pygame.display.set_mode((user_x, user_y))
  2. 接下来,创建一个具有您想要支持的最高分辨率的pygame.Surface。 surface = pygame.Surface((1920, 1080))
  3. 然后,把所有东西都搞定到那个表面。 surface.blit(image, rect) # Etc...
  4. 完成所有blits后,将表面(根据需要)缩小到用户所需的任何分辨率。优选地,您只允许具有相同宽高比的分辨率。 pygame.transform.scale(surface, ((screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=surface)
  5. 最后,将表面blit到屏幕,然后显示它。 screen.blit(surface, (0, 0)) pygame.display.update()

此过程(缩小)允许您保留图像质量,同时仍允许用户选择其屏幕分辨率。因为你经常操纵图像会慢一些。

© www.soinside.com 2019 - 2024. All rights reserved.