【问题标题】:LibGDX - Sprite / Pixmap / Camera / ViewPort sizes (width/height ) - algorithm of all size transformations from PixMap to (physical device) ScreenLibGDX - Sprite / Pixmap / Camera / ViewPort 大小(宽度/高度) - 从 PixMap 到(物理设备)屏幕的所有大小转换的算法
【发布时间】:2020-09-05 07:26:15
【问题描述】:

我的完整思维算法是什么,可以理解路径上所有可能的宽度/高度变换 PixMap -> (physical) Screen/monitor

抱歉这个愚蠢的问题,但是这些尺寸如何相互关联/缩放/交互?

我在屏幕上实际看到的尺寸是多少?会发生什么缩放效果?

我需要快速入门,但谷歌搜索并不能提供直接和系统的答案。

PixMap 是图片/图像(来自文件或一些以编程方式绘制的图元),其宽度/高度以像素为单位

稍后此 PixMap 将显示在某些物理设备的物理屏幕上。据我了解,实际上它只会显示在物理设备屏幕的一部分中-仅在我的游戏的应用程序窗口中(config.width / config.height in LwjglApplicationConfiguration)-我猜它是以像素为单位的......

PixMap 被包装到 Texture 中(我不完全理解为什么 - OpenGL 说 Texture 是一个或多个图像的容器,但新的 Texture(PixMap) 只需要一个 PixMap)。 Texture 没有任何尺寸(好吧,它只是 PixMap(s) 的容器。

现在 Texture 被包裹到 Sprite (new Sprite(Texture)) 中。 Sprite 有自己的宽度/高度。 Sprite 是我游戏的一些可见部分(移动机器人、球、坦克、导弹等)。所以 Sprite 大小会覆盖 PixMap 大小,因此会以某种方式导致缩放?

但是我在屏幕上实际看到的 Sprite 大小是什么(如果我从未调用过 sprite.scale())? sprite.setSize(float, float) - 表示高度/宽度(以像素为单位)??? Sprite 能否自动将大小设置为与底层 PixMap 完全相同?

现在Camera 大小 - 相机是用户在屏幕上实际看到的(游戏世界的一部分,可能比屏幕大),对吧?所以我可以将相机大小设置为等于 Gdx 应用程序窗口(启动器类中的 config.width / config.height)?还是相机尺寸定义了物理屏幕的可见(显示给用户)部分?如果我的游戏适合整个屏幕,我可以将相机尺寸设置为等于屏幕尺寸,仅此而已。为什么我需要相机?我想我无法完全理解相机。

还有ViewPort - 它与Camera“相同”(它管理Camera)。但是我看到 ExtendViewPort 和 ScalingViewPort “篡改”了缩放,所以他们调整了我的 Sprite/PixMap/Camera 大小?

此外,所有ViewPort 类的构造函数中都有minHeight/minWidth - 另一个大小转换/缩放?

附:另一个问题是所有这些情况下的坐标。什么相对于什么?

answer 也部分相关且有帮助。

【问题讨论】:

    标签: java camera libgdx sprite pixmap


    【解决方案1】:

    我将仅针对 2D 情况进行解释,这意味着您仅使用 OrthographicCamera(而不是 PerspectiveCamera)。

    OrthographicCamera 用某种宽度和高度的虚拟单位定义了一个进入世界的窗口。这些单位可以是您想要的任何单位(例如游戏中的仪表)。相机的viewportWidthviewportHeight 变量定义了您正在查看游戏世界的窗口的大小。这个窗口被拉伸以适应设备的屏幕,所以通常,您会希望viewportWidthviewportHeight 的比例与屏幕宽度与屏幕高度的比例相同,这样图像不会看起来失真。

    并非所有屏幕都具有相同的纵横比,因此 Viewport 类充当 OrthographicCamera 管理器,可以自动调整相机的 viewportWidthviewportHeight 并进行信箱处理以防止失真。信箱化是指它可以减少相机图像被拉伸到的屏幕区域。

    纹理确实有一个高度和宽度,这将与它加载的像素图相匹配。有一个不同的类,TextureArray,用于多个图像。您可能永远不会直接将其用于 2D 游戏。

    像素图是加载到堆内存的图像数据。从像素图创建纹理意味着它将图像数据传输到 GPU 内存,以便与 OpenGL 一起使用。

    Sprite 是 TextureRegion 的子类。 TextureRegion 是进入纹理一部分的窗口。

    IMO,您几乎不应该使用 Sprite 类。将其作为 TextureRegion 的子类(违反组合而不是继承)是一个不幸的设计决定,并且它将图像资产与特定的游戏对象混为一谈。相反,您应该创建自己的 GameObject 类,该类具有 TextureRegion 变量和您实际要使用的位置/缩放参数。

    当您绘制一个 TextureRegion 并且不提供明确的宽度和高度时,它会在假设原始图像中的每个像素与您的虚拟游戏单元之一大小相同的情况下绘制到游戏世界。你应该做这样的事情的唯一情况是,如果你的游戏应该具有带有大像素图形的复古外观。否则,您将需要使用与游戏世界单位中它应该看起来有多大相对应的明确宽度和高度来绘制它。

    此外,在绘制 TextureRegion 时,x 和 y 参数是其左下角在游戏世界坐标系中的位置。它可能完全可见,也可能不完全可见,具体取决于它是否放置在游戏世界中可以通过 OrthographicCamera 的窗口查看的位置(其位置可以在 X 和 Y 方向移动)。

    所以总结一下如何管理这一切:

    如果您正在制作“复古”图形并且更喜欢以像素为单位:

    1. 决定您想在屏幕上看到多少像素的艺术品。将这些作为 ExtendViewport 构造函数的 minWidthminHeight 参数传递。您也可以使用 FitViewport,但 IMO 用户对信箱处理感到恼火。我认为,如果您将游戏提交到带有信箱功能的 iOS App Store,他们会直接拒绝。
    2. 将您的艺术资产设为 1 像素与 1 像素的比例。
    3. 绘制 TextureRegions 时,无需指定宽度和高度。

    否则:

    1. 以米为单位考虑您的游戏世界。决定一次应该看到多少米的游戏世界,并将它们作为 ExtendViewport 构造函数的minWidthminHeight 参数传递。
    2. 确定您希望游戏显示的图形分辨率,并以足够高的分辨率保存资源以匹配。例如,如果您希望您的艺术作品在 1080 像素高的屏幕上看起来清晰,并且您的相机的 minHeight 是 3 米,那么您的 1m 高角色的源图像 1 / 3 * 1080 = 360 应该有 360像素高度。
    3. 绘制 TextureRegions 时,以游戏世界的米为单位提供资产的宽度和高度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-29
      • 2016-01-17
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 2016-09-09
      • 2012-08-23
      相关资源
      最近更新 更多