【问题标题】:How can i make all the images on a window scale down or up with the size of the monitor我怎样才能使窗口上的所有图像随着显示器的大小而缩小或放大
【发布时间】:2015-04-27 20:19:32
【问题描述】:

所以我正在用 python 和 pygame 制作游戏,并且我有这样的 indow 设置

display = pygame.display.set_mode((0,0), pygame.FULLSCREEN)

这使窗口的大小约为 1334 X 800,因此我将所有精灵和背景都基于该大小的屏幕,但正如您所知,并非每个人的屏幕大小都与我相同,所以我的问题是如何使图像按比例缩放显示器屏幕有多大

(P.S游戏是全屏模式)

【问题讨论】:

  • 渲染到一个巨大的表面然后缩放整个表面缓冲区实际上可能更简单,而不是缩放每个精灵和背景。在合成之后进行插值看起来也比之前更好。 (它也可能更快......但它也可能更慢,而且更有可能无关紧要。)
  • 同时,如果某人的屏幕与您的屏幕纵横比不同,您是要拉伸所有内容、整个游戏的信箱,还是什么?例如,假设某人有一个 1334x1600 的疯狂垂直屏幕。所以你希望所有的精灵都保持相同的宽度但变成两倍高?或者保持相同的大小,但屏幕的顶部和底部是空白的?还是有什么不同?

标签: python pygame


【解决方案1】:

首先,你如何获得分辨率和比例因子?

这很棘手,因为某人的屏幕可能与您的 1334x800 的宽高比不同。您可以使用信箱(以各种不同的方式)或拉伸精灵;你需要决定你想要什么,但我会展示一种可能的信箱:

NOMINAL_WIDTH, NOMINAL_HEIGHT = 1334., 800.
surface = display.get_surface()
width, height = surface.get_width(), surface.get_height()
xscale = width / NOMINAL_WIDTH
yscale = height / NOMINAL_HEIGHT
if xscale < 1 and yscale < 1:
    scale = max(xscale, yscale)
elif xscale > 1 and yscale > 1:
    scale = min(xscale, yscale)
else:
    scale = 1.0

现在,如何缩放每个精灵和背景?

首先,您确定要这样做吗?仅转换整个表面可能更简单。如果没有测试,很难预测这是更慢还是更快(并且可能无论如何都不相关),但它肯定会看起来更好(因为任何插值,抖动,抗锯齿等都发生在合成之后,而不是之前 - 除非你要去当然,对于那个 8 位外观,在这种情况下它会破坏外观……)。为此,您可以将所有内容合成到 1334x800 的屏幕外表面(或者,更好的是,将所有内容放大一个常数因子),然后 transforming 该表面进行显示。 (注意transform 方法包含一个可选的DestSurface 参数。您可以使用它直接从屏幕外表面转换到显示器表面。)


但是让我们假设你想按照你要求的方式去做。

您可以在加载精灵时执行此操作。例如:

def rescale(surf, scale):
    new_width, new_height = surf.get_width() * scale, surf.get_height() * scale
    return pygame.transform.smoothscale(surf, (new_width, new_height))

class ScaledSprite(pygame.sprite.Sprite):
    def __init__(self, path, scale):
        pygame.sprite.Sprite.__init__(self)
        self.image = rescale(pygame.image.load(path), scale)
        self.rect = self.image.get_rect()

背景也一样。

【讨论】:

    【解决方案2】:

    来自this SO question,可以通过

    获取显示器的尺寸
    infoObject = pygame.display.Info()
    

    获取屏幕的高度和宽度为infoObject.current_winfoObject.current_h

    然后您可以使用这些值来适当地缩放所有内容。

    【讨论】:

    • 他不需要这个;他将显示器设置为全屏,所以它的表面尺寸通常是显示器的尺寸——在极少数情况下,它不是他想要的表面尺寸。
    • 您可以根据其他 SO 问题使用全屏显示的显示尺寸获取显示尺寸
    • 是的,你可以——但同样,如果你已经创建了一个这样大小的表面,你就不需要像 OP 那样。
    • 您可以使用display = pygame.display.set_mode((0,0), pygame.FULLSCREEN) 创建表面,您不传递屏幕大小,默认为全屏。为了使小屏幕能够捕获所有内容并且大屏幕没有空白空间,您需要获取屏幕的大小。所以是的,你确实需要获得全屏的大小......
    • 当然可以; OP 正在以这种方式创建表面。但是你可以得到那个表面的高度和宽度。这意味着如果您添加窗口模式,您的代码将继续工作而无需任何更改,在全屏表面小于显示器等罕见的边缘情况下,您会得到正确的答案,等等。
    猜你喜欢
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2012-10-28
    • 2023-03-30
    • 2020-10-02
    • 1970-01-01
    相关资源
    最近更新 更多