【问题标题】:Expanding textures in libGDX在 libGDX 中扩展纹理
【发布时间】:2016-12-13 17:47:41
【问题描述】:

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

Everything allright 在这张图片上你可以看到跳跃前的比赛。

Wider textures 这是跳跃后的游戏。在玩家头上也能清晰的看到。

更多细节。我不使用block2d。瓷砖尺寸为 8x8 缩放为 20x20。使用没有填充的纹理打包器(无论如何填充都会出现问题)。我不知道要发布哪个代码,因为我不知道问题可能出在哪里,所以这里只是简单的块类。任何帮助将不胜感激,谢谢。

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);

}

【问题讨论】:

    标签: java libgdx rendering tile


    【解决方案1】:

    欢迎来到 libGDX!

    TL;DR-那里没有足够的代码来说明确切的问题是什么,但我猜你代码中的某个地方将像素空间与游戏空间混淆了。

    观点问题

    当您第一次创建 2D 的 libGDX 游戏时,很容易认为您只是在屏幕上绘制像素。毕竟,您的屏幕以像素为单位,您的窗口以像素为单位,您的纹理以像素为单位。

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

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

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

    游戏单位

    那么我们如何衡量某物的“真实大小”呢?答案是我们可以使用我们想要的任何类型的单位来测量它!我们可以说某物有 3.5 米长,或 42 根香蕉——随便你!为了便于讨论,我将把这些单元称为“游戏单元”(GU)。

    对于您的游戏,您可能会考虑让每个块高 1 个 GU,宽 1 个 GU(本质上是用块来衡量您的游戏世界)。你的角色可以移动一个方块的一小部分,但你用“每秒方块”来衡量速度。我几乎可以保证它会让你的游戏逻辑更简单。

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

    您可能已经知道,您的游戏使用三样东西进行渲染:视口(可以在屏幕上绘制游戏的区域)、相机(将其想象成真正的相机 - 您可以更改位置和大小镜头来改变“视野”中你的世界的多少)和你的游戏对象(你可能想画也可能不想画的东西,取决于它们是否对相机可见)。

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

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

    现在 libGDX 将所有这些尺寸默认为 1 GU == 1 像素,这会误导很多人认为一切都是以像素来衡量的。一旦您意识到情况并非如此,就会产生一些非常酷的含义。

    非常酷的含义

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

    如果屏幕尺寸发生变化(例如更改为 1440x900),我的游戏仍将在屏幕上显示 40x30 块。如果纵横比发生变化,它们可能看起来有点拉伸,但 libGDX 有 special viewports 可以为您抵消这一点。这样可以更轻松地在其他显示器、其他设备上支持您的游戏,甚至只是处理屏幕大小调整。

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

    第三个很酷的含义是,这使您的游戏逻辑更加清晰。例如,您开始以“每秒游戏单位数”而不是“每秒像素数”来考虑速度。这意味着 绘图大小 的变化不会影响游戏中事物的速度,并且会为您节省大量寻找错误的时间。您还避免了很多奇怪的“我调整屏幕大小时跳跃行为不同”的错误。

    总结

    我希望这会有所帮助并且有意义。一开始很难让你的想法围绕它,但从长远来看,它会让你的生活变得更轻松,你的游戏也会变得更好。如果您想要一个更好的图片示例,我建议您阅读其中一位 libGDX 开发人员的this article。

    【讨论】:

    • John,别再浪费时间在 StackOverflow 上,写一本 LibGDX 书了! :-)
    • 非常感谢您提供如此详细的回答!首先我使用了box2D(然后我意识到它对这种类型的游戏没有用)并且我不得不将所有内容按“每米像素”按比例缩小,因为box2D逻辑使用某种米作为单位并且它没有很有意义。但现在我想,我明白了,所以我会以某种方式更改代码并希望它能解决这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2013-02-09
    相关资源
    最近更新 更多