Java 在libGDX中扩展纹理

Java 在libGDX中扩展纹理,java,libgdx,rendering,tile,Java,Libgdx,Rendering,Tile,我正在使用libgdx制作简单的基于平铺的游戏,一切似乎都很好,直到我添加了一个矩形,它跟随鼠标位置。我发现,每当我跳转时,矩形(以及其他块)可能会扩展1 px,直到我让空格键。当我再次按下空格键时,它会恢复到正常大小。我试着打印出矩形的宽度和高度,但它们并没有改变,所以问题在于渲染 在这张图片上你们可以看到跳跃前的游戏 这是一场接一场的比赛。你也可以在球员的头上清楚地看到它 再详细一点。我不使用block2d。瓷砖尺寸为8x8,比例为20x20。在不填充的情况下使用texturepacke

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

在这张图片上你们可以看到跳跃前的游戏

这是一场接一场的比赛。你也可以在球员的头上清楚地看到它

再详细一点。我不使用block2d。瓷砖尺寸为8x8,比例为20x20。在不填充的情况下使用texturepacker(填充仍会出现问题)。我不知道该发布哪段代码,因为我不知道问题出在哪里,所以这里只是一个简单的块类。任何帮助都将不胜感激,谢谢

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-那里没有足够的代码来说明确切的问题是什么,但我猜在代码中的某个地方,你把像素空间和游戏空间混淆了

透视问题 当你第一次创建一个二维的libGDX游戏时,你很容易认为你只是在屏幕上画像素。毕竟,你的屏幕是以像素为单位测量的,你的窗口是以像素为单位测量的,你的纹理是以像素为单位测量的

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

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

作为旁注,虽然您可能正在使用正交摄影机(即没有透视的摄影机)绘制二维精灵,但libGDX实际上是在幕后绘制平面三维对象(平面)

游戏单位 那么,我们如何衡量事物的“真实大小”?答案是我们可以用我们想要的任何类型的单位来测量它!我们可以说有些东西有3.5米长,或者42根香蕉——你想要什么都行!为了这次对话,我将把这些单位称为“游戏单位”(GU)

对于你的游戏,你可以考虑让每一个街区一个高一个宽(基本上衡量你的游戏世界的块)。你的角色可以移动一个方块的分数,但你可以用“每秒方块数”来衡量速度。我几乎可以保证这会让你的游戏逻辑简单得多

但是我们的纹理是以像素为单位的! 正如您可能已经知道的,您的游戏使用三种东西进行渲染:视口(可以绘制游戏的屏幕补丁)、摄影机(将其视为真实的摄影机-您可以更改镜头的位置和大小以更改“在视图中”的世界面积),以及游戏对象(你可能想画或不想画的东西,取决于它们是否对相机可见)

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

  • 视口:这是一块屏幕(设置为游戏窗口的大小),因此以像素为单位
  • 相机:相机很有趣,因为它的大小和位置是以游戏单位而不是像素来测量的。因为视口使用相机来知道在屏幕上绘制什么,所以它确实包含了GU到像素的映射
  • 游戏对象:这是以游戏单位测量的。它的纹理可能以像素为单位,但与游戏对象的“真实大小”不同
现在libGDX默认所有这些大小,例如1 GU==1像素,这误导了很多人,让他们认为所有东西都是用像素来衡量的。一旦你意识到事实并非如此,就会有一些非常酷的含义

真的很酷 第一个含义是,即使我的屏幕大小改变,我的相机大小也可以保持不变。例如,如果我有一个800x600像素的小屏幕,我可以将我的相机大小设置为40x30。这保持了良好的纵横比,并允许我在屏幕上绘制40x30块

如果屏幕大小发生变化(比如1440x900),我的游戏仍然会在屏幕上显示40x30块。如果纵横比发生变化,这些块可能看起来有点拉长,但libGDX有这样的功能,这将抵消这一点。这使得在其他显示器、其他设备上支持游戏变得更加容易,甚至可以仅处理屏幕大小调整

第二个很酷的暗示是,你在很大程度上不再关心纹理大小。如果你开始告诉libGDX“嘿,在这个1x1 GU对象上画这个32x32px精灵”,而不是“嘿,画这个32x32px精灵”(注意区别?)这意味着改变纹理大小不会改变屏幕上的东西的绘制方式,而是会改变它们的详细程度。如果你想改变它们的绘制方式,你可以将相机大小改为“放大”

第三个很酷的暗示是,这让你的游戏逻辑更加清晰。例如,你开始考虑“游戏单位/秒”的速度,而不是“像素/秒”。这意味着绘图大小的更改不会影响游戏中的速度,并将为您节省大量后续的bug搜索。您还可以避免许多奇怪的“调整屏幕大小时我的跳转行为不同”bug

总结 我希望这是有帮助的和有意义的。一开始很难让你的思想围绕着它,但它会让你的生活变得更轻松,你的生活也会变得更好