繁体   English   中英

LibGDX - Sprite / Pixmap / Camera / ViewPort 大小(宽度/高度) - 从 PixMap 到(物理设备)屏幕的所有大小转换的算法

[英]LibGDX - Sprite / Pixmap / Camera / ViewPort sizes (width/height ) - algorithm of all size transformations from PixMap to (physical device) Screen

什么是我完整的思考算法来理解路径PixMap -> (physical) Screen/monitor所有可能的宽度/高度转换

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

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

我需要一个快速入门,但谷歌搜索不会产生直接和系统的答案。

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

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

PixMap被包装到Texture中(我不完全理解为什么 - OpenGL 说 Texture 是一个或多个图像的容器,但是 new 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 应用程序 Window(启动器类中的 config.width / config.height)? 还是相机尺寸定义了物理屏幕的可见(显示给用户)部分? 如果我的游戏适合整个屏幕,我可以将相机尺寸设置为等于屏幕尺寸,仅此而已。 为什么我需要相机? 我想我无法完全理解相机。

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

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

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

这个答案也部分相关且有帮助。

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

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

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

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

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

Sprite 是 TextureRegion 的子类。 TextureRegion 是一个 window 成为纹理的一部分。

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

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

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

总结一下如何管理所有这些:

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

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

否则:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM