LibGDX-B/W图像将黑色渲染为透明,白色渲染为黑色

LibGDX-B/W图像将黑色渲染为透明,白色渲染为黑色,libgdx,scene2d,Libgdx,Scene2d,长期读者,第一次海报。。。我正在使用LibGDX和Scene2D将iOS SpriteKit应用程序翻译成Android。我慢慢地掌握了窍门,但我有一个奇怪的形象问题,我无法控制自己。我有三个黑白图像,我在我的游戏板上作为瓷砖使用。在每种情况下,当我将它们添加到舞台上时,它们渲染时黑色部分透明,白色部分黑色。以下是一个例子: 这是我的定制课程 public class Tile extends Actor { private int value; private Image prime; pr

长期读者,第一次海报。。。我正在使用LibGDX和Scene2D将iOS SpriteKit应用程序翻译成Android。我慢慢地掌握了窍门,但我有一个奇怪的形象问题,我无法控制自己。我有三个黑白图像,我在我的游戏板上作为瓷砖使用。在每种情况下,当我将它们添加到舞台上时,它们渲染时黑色部分透明,白色部分黑色。以下是一个例子:

这是我的定制课程

public class Tile extends Actor {
private int value;
private Image prime;
private Label label;
private boolean isPrime;
private Rectangle r;

Tile(int number, boolean primeSquare, Rectangle rect, float textSize) {
    value = number;
    r = rect;

    if (primeSquare) {
        isPrime = true;
        prime = new Image(new Texture(Gdx.files.internal("prime_background.png")));
        prime.setBounds(r.x, r.y, r.width, r.height);
    } else {
        isAvailable = true;
    }

    Label.LabelStyle style = new Label.LabelStyle(Fonts.bold(textSize), Color.BLACK);
    label = new Label(Integer.toString(number), style);
    label.setBounds(r.x, r.y, r.width, r.height);
    label.setAlignment(Align.center);
}

@Override
public void draw(Batch batch, float parentAlpha) {
    if (isPrime) {
        prime.draw(batch, parentAlpha);
        label.draw(batch, parentAlpha);
    }

}
我还有另外两张黑白照片,我在这堂课上也试过,它们也有同样的问题。我替换了一幅全彩图像,它的渲染正确,没有问题

黑白图像是否有什么特殊之处会导致它们以这种方式渲染?有没有其他可能导致我忽略的情况

这一切都是通过我的自定义屏幕类呈现的,我觉得这是一种非常普通的方式:

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    stage.act(Gdx.graphics.getDeltaTime());
    stage.draw();
}
任何帮助都将不胜感激。谢谢


这是我能找到的最接近的线程:

灰度PNG文件可能是8位(纯alpha通道)或16位(一个颜色(“亮度”)通道和一个alpha通道)。我不知道你有哪些,因为纹理加载行为没有明确的记录,但我猜你保存了一个8位图像。OpenGL将把这个单一通道视为alpha(透明度),并添加一个纯黑色的颜色通道。这将产生您在屏幕截图中显示的内容

假设您在数字后面绘制此图像,因此根本不需要透明度,最简单的解决方案是使用纯白色alpha通道保存源PNG文件,使其成为16位图像。如果这给您带来麻烦,请将它们另存为全彩32位PNG

顺便说一句,
新纹理
不应在您的演员文件中使用。纹理是一个沉重的对象,并且还使用必须清理的本机内存,以防止内存泄漏。Java垃圾收集器不会自动清理本机分配的内存。通过在游戏的每个平铺中创建一个新纹理,您可以无理由多次将同一图像加载到内存中。如果在引用丢失之前不调用纹理上的
dispose()
,则内存正在泄漏

最佳实践是使用一个中心资源类,在其中加载所有纹理。可以将对同一纹理的引用传递给每个平铺构造函数。当游戏关闭时,您的资产类应该处理它加载的所有东西(
game.dispose()


事实上,LibGDX已经有了一个用于此目的的内置AssetManager类。您可以在文档中阅读它。

灰度PNG文件可能是8位(纯alpha通道)或16位(一个颜色(“亮度”)通道和一个alpha通道)。我不知道你有哪些,因为纹理加载行为没有明确的记录,但我猜你保存了一个8位图像。OpenGL将把这个单一通道视为alpha(透明度),并添加一个纯黑色的颜色通道。这将产生您在屏幕截图中显示的内容

假设您在数字后面绘制此图像,因此根本不需要透明度,最简单的解决方案是使用纯白色alpha通道保存源PNG文件,使其成为16位图像。如果这给您带来麻烦,请将它们另存为全彩32位PNG

顺便说一句,
新纹理
不应在您的演员文件中使用。纹理是一个沉重的对象,并且还使用必须清理的本机内存,以防止内存泄漏。Java垃圾收集器不会自动清理本机分配的内存。通过在游戏的每个平铺中创建一个新纹理,您可以无理由多次将同一图像加载到内存中。如果在引用丢失之前不调用纹理上的
dispose()
,则内存正在泄漏

最佳实践是使用一个中心资源类,在其中加载所有纹理。可以将对同一纹理的引用传递给每个平铺构造函数。当游戏关闭时,您的资产类应该处理它加载的所有东西(
game.dispose()


事实上,LibGDX已经有了一个用于此目的的内置AssetManager类。您可以在文档中详细阅读。

谢谢!这起作用了。我最初是在PowerPoint中创建图像的,我想ppt默认为8位灰度图像。在Photoshop中保存为16位,问题消失了。:)另外,我还将改变我的纹理加载-我注意到瓷砖加载缓慢。也谢谢你!谢谢这起作用了。我最初是在PowerPoint中创建图像的,我想ppt默认为8位灰度图像。在Photoshop中保存为16位,问题消失了。:)另外,我还将改变我的纹理加载-我注意到瓷砖加载缓慢。也谢谢你!