在 libGDX 中扩展纹理

Expanding textures in libGDX

我正在使用 libgdx 制作简单的基于图块的游戏,一切似乎都很好,直到我添加了一个跟随鼠标位置的矩形。我发现,每当我跳跃时,矩形(以及其他块)可能会扩展 1 像素,直到我放开空格键。当我再次按下空格键时,它会变成正常大小。我试着打印出矩形的宽度和高度,但它们没有改变,所以问题出在渲染上。

Everything allright 这张图可以看到跳跃前的游戏。

Wider textures 这是跳跃后的游戏。玩家头上也能看的很清楚

再详细一点。我不使用 block2d。瓷砖尺寸从 8x8 缩放到 20x20。在没有填充的情况下使用 texturepacker(无论如何填充都会出现问题)。我不知道 post 的代码,因为我不知道问题出在哪里,所以这里只是简单的块 class。非常感谢任何帮助,谢谢。

public class Block extends Sprite {

private int[] id = { 0, 0 };
public Rectangle rect;
private int textureSize = 8;

public Block(PlayScreen play,String texture, int x, int y, int[] id) {
    super(play.getAtlas().findRegion("terrain"));
    this.id = id;
    rect = new Rectangle(x, y, ID.tileSize, ID.tileSize);
    setRegion(id[0] * textureSize, id[1] * textureSize + 32, textureSize, textureSize);
    setBounds(rect.x, rect.y, rect.width, rect.height);
}

public void render(SpriteBatch batch) {
    draw(batch);

}

欢迎来到libGDX!

TL;DR- 您的代码不足以说明确切的问题所在,但我猜您在代码中的某处将 pixel-space 与 game-[= 混淆了99=].

视角问题

当您第一次创建 libGDX 2D 游戏时,您很容易认为您只是在屏幕上绘制像素。毕竟,你的屏幕是用像素来衡量的,你的window是用像素来衡量的,你的纹理也是用像素来衡量的。

但是,如果您开始仔细观察 API,您会发现一些奇怪的小东西,例如您的相机和精灵位置和大小被测量为 浮点值 而不是整数(为什么要浮点数?你不能有一个像素的一小部分!)。

游戏对象的尺寸与绘制的尺寸不同的原因。在 3D 世界中理解这一点真的很容易——当我靠近某物时,它在屏幕上被绘制得非常大。当我离得很远的时候,它画得很小。物体的实际大小不会根据我与它的距离而改变,但 感知 大小会改变。这告诉我们,我们不能仅仅根据它们的绘制方式来安全地衡量游戏中的事物——我们必须根据它们的 真实大小.

来衡量

附带说明一下,虽然您可能正在使用正交相机(即没有透视的相机)并绘制 2D 精灵,但 libGDX 实际上是在幕后绘制平面 3D 对象(平面)。

游戏单位

那么我们如何衡量某物的 "true size" 呢?答案是我们可以使用我们想要的任何类型的单位来衡量它!我们可以说某个东西长 3.5 米,或 42 根香蕉——随便你怎么说!为了这次谈话,我将这些单位称为 "Game Units" (GU)。

对于您的游戏,您可以考虑让每个方块高 1 GU 宽 1 GU(本质上以方块为单位衡量您的游戏世界)。您的角色可以移动一个方块的几分之一,但是您根据 "blocks per second." 来衡量速度,我几乎可以保证它会使您的游戏逻辑简单得多。

但是我们的纹理是以像素为单位的!

您可能已经知道,您的游戏使用三样东西来渲染:视口(可以绘制游戏的屏幕补丁)、相机(把它想象成一个真正的相机 - 你改变位置和镜头的大小来改变你的世界有多少'in view'),以及你的游戏对象(你可能想画也可能不想画的东西,取决于它们是否对相机可见)。

现在让我们看看它们是如何测量的:

  • 视口: 这是屏幕的一块(设置为游戏的大小 window),因此以像素为单位。
  • 相机: 相机很有趣,因为它的大小和位置是用游戏单位而不是像素来衡量的。由于视口使用相机知道要在屏幕上绘制什么,因此它确实包含 GU 到像素的映射。
  • 游戏对象: 这是以游戏单位衡量的。它可能具有以像素为单位测量的纹理,但与游戏对象的 "true size" 不同。

现在 libGDX 默认设置所有这些尺寸,例如 1 GU == 1 像素,这误导了很多人,让他们认为一切都以像素为单位。一旦您意识到事实并非如此,就会发现一些非常酷的含义。

非常酷的含义

第一个含义是即使我的屏幕尺寸发生变化,我的相机尺寸也可以保持不变。例如,如果我有一个 800x600 像素的小屏幕,我可以将相机尺寸设置为 40x30。这保持了很好的宽高比,并允许我在屏幕上绘制 40x30 块。

如果屏幕尺寸发生变化(例如 1440x900),我的游戏仍会在屏幕上显示 40x30 块。如果宽高比发生变化,它们可能看起来有点拉伸,但 libGDX 有 special viewports 可以为您抵消这种情况。这使得在其他显示器、其他设备上支持您的游戏变得更加容易,甚至只是处理屏幕大小调整。

第二个很酷的含义是您在很大程度上不再关心纹理大小。如果您开始告诉 libGDX "Hey, go draw this 32x32px sprite on this 1x1 GU object" 而不是 "Hey, go draw this 32x32px sprite"(注意到区别了吗?)这意味着改变纹理大小不会改变 big 的大小屏幕上的内容已绘制,它会改变 详细程度 的方式。如果您想更改绘制的大小,可以将相机大小更改为 'zoom in.'

第三个很酷的含义是,这会使您的游戏逻辑更加清晰。例如,您开始考虑 "Game Units per second" 中的速度,而不是 "Pixels per second"。这意味着 绘图大小 的变化不会影响游戏中的速度,并且会在以后为您节省大量寻找错误的时间。您还可以避免很多奇怪的 "My jump behaves differently when I resize the screen" 错误。

总结

我希望这对您有所帮助并且有意义。一开始很难理解它,但从长远来看,它会让你的生活更轻松,游戏也会更好 运行。如果您想要更好的图片示例,我建议您阅读 libGDX 开发人员之一的 this article