【问题标题】:LibGDX - setProjectionMatrix() "hiding" a SpriteLibGDX - setProjectionMatrix() “隐藏”一个 Sprite
【发布时间】:2020-10-28 06:34:23
【问题描述】:

我正在尝试绘制一个Sprite,但是当我第一次运行我的程序时它只出现一个框架,然后立即消失。我正在使用一个Stage、一个平铺地图和两个Batches,我希望这不是问题。

看起来精灵隐藏在其他东西后面,但我完全确定它后面没有任何东西被绘制。因此,经过长时间的折腾,我发现删除 setProjectionMatrix() 方法“解决了”我的问题,因为精灵以某种方式完美显示。

我完全不明白发生这种情况的原因,我不想只是删除该方法并让精灵跟随相机,所以:

为什么或如何使用 setProjectionMatrix() 方法“隐藏”Sprite?它是否改变了我的精灵绘制的顺序?最重要的是,我该如何解决?

这是我的render 方法:

public void render(float delta) {
    Render.cleanScreen(); //Render is a class i made with useful static stuff, like the Batch i am using.
                          //This method is pretty much just a Gdx.gl.glClearColor() method.
    
    tmr.setView(camera); // tileMapRenderer
    tmr.render();
    b2dr.render(world, camera.combined); // Box2DDebugRenderer
    stage.act();
    stage.draw();
    
    Render.batch.begin(); 
    sprite2.draw(Render.batch); //The sprite i want to draw
    Render.batch.end();

    hudBatch.begin();
    sprite1.draw(hudBatch); //This works fine
    hudBatch.end();

    Render.batch.setProjectionMatrix(camera.combined);
    Gdx.input.setInputProcessor(stage);
}

编辑:有人要求提供额外信息,所以:

This 是我的游戏使用 setProjectionMatrix 时的样子(在 Sprite 消失的第一帧之后),this 是我删除它时的样子。您可以清楚地看到红色方块(Sprite)。

• 我目前正在使用 FitViewport。

【问题讨论】:

  • camera 是舞台使用的同一个相机实例吗?
  • 是的,是同一台相机。
  • 投影矩阵不会改变绘制顺序,但理论上它可以将你的精灵绘制在其他精灵之后,如果它已经在 Z 方向移动并且深度测试开启(它应该'不是如果你没有打开它)。但如果是你在各处使用的同一台相机,并且你没有修改它的参数,那也不可能。
  • 比较使用和不使用投影矩阵的屏幕截图可能会有所帮助。并知道您正在使用哪个视口。
  • 您说 Sprite 看起来像是隐藏在其他东西后面,但在我看来,它似乎什么都没有显示?那正确吗?您的 FitViewport 尺寸是否恰好与窗口尺寸匹配?否则我无法想象在不使用相机时如何将 Sprite 绘制在您期望的位置。

标签: java libgdx


【解决方案1】:

Stage.draw() 在舞台的视口上调用apply(),但永远不会将 OpenGL 视口恢复到之前的状态。我猜你的舞台使用 FitViewport,所以它正在裁剪屏幕的一部分。如果您希望在舞台外绘制的内容具有不同的视口行为,您应该为此创建一个单独的视口,并在开始渲染其他内容之前调用 viewport.apply()

旁注:如果您延迟加载使用本机内存的任何内容(例如 SpriteBatch 和 Texture,实现 Disposable 的东西)并将引用存储在静态变量(您的 Render 类)中,请确保将其全部释放并为空在游戏的destroy() 方法中输出。否则,在 Android 上,您将泄露这些内容,并且在您重新打开游戏时将无法正常工作。

另一个注意事项:在我看来,Sprite 类不应该被使用,除非你有数百个并且它们没有移动太多(在这种情况下它的性能可能会稍微好一些)。 Sprite 是资产(TextureRegion)和游戏状态数据的奇怪组合。因此,它可能会产生您必须解决的设计问题,例如当您想要为其设置动画或翻转它时。最好创建自己的 GameObject 类,它引用一个 TextureRegion(它的单个实例可以被许多元素共享),并且有自己的位置、颜色、旋转等变量。然后用适当的 SpriteBatch.draw 绘制它使用这些属性的方法。在我的游戏中,我有一个围绕TextureRegion 的包装接口,它可以交替包装Animation<TextureRegion>,因此我的GameObject 类可以使用其中任何一个,并且可以轻松交换。这使代码更灵活地更改。

【讨论】:

  • 感谢您的回复。我明白你在说什么,但我还是有点困惑。我不想要两个不同的视口,我希望我的 Sprite2 适合我已经拥有的东西。所以这就是我不明白您的回复:如果我在我的主屏幕中声明并创建了 FitViewport,并在我第一次创建它时将它传递给我的舞台,为什么不更新 OpenGL 视口?我创建的视口不应该“协调”两者吗?
  • 我在猜测可能是什么问题,但如果您想对所有内容使用相同的视口,请忽略我所说的。这是另一回事。
【解决方案2】:

所以...我刚刚意识到我的同事不小心删除了 viewport.update() 方法。

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

【讨论】:

    猜你喜欢
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2016-02-27
    • 2018-06-23
    相关资源
    最近更新 更多