Libgdx 在运行时更改纹理的颜色

2022-01-12 00:00:00 colors textures java libgdx

在使用 libgdx 制作的游戏中,我有一个 TextureAtlas,其中存储了我的 Animation 的所有 TextureRegion代码>播放器.Player 默认有一件蓝色 T 恤(例如).现在我希望能够拥有多个 Player 并且每个都应该有另一种 T 恤颜色.所以基本上,我想将第二个 Player 的蓝色替换为红色,第三个 Player 替换为绿色,依此类推.我确信我可以用 PixMap 做到这一点,但不会.因为那样我就失去了 TextureAtlas(?) 的优势.还有另一种方法可以做到这一点吗?或者我需要在 TextureAtlas 中将每个颜色版本"作为 TextureRegion 吗?

In a game made with libgdx I have a TextureAtlas in which I have stored all the TextureRegions for my Animations of the Player. The Player by default has a blue T-Shirt (for example). Now I would like to be able to have more then one Player and each should have another T-Shirt color. So basically, I want to replace the blue with red for the second Player and with green for the 3rd Player and so on. I am sure I can do this with PixMap but wouldn't. Because then I lose the advantage of the TextureAtlas(?). Is there another way to do this? Or do I need to have every "color version" as a TextureRegion in the TextureAtlas?

另一个小问题:
使用 Gimp(可能还有一些其他程序),您可以为.gif"文件使用颜色索引.通过为文件中的每种颜色保存一个索引,然后使用该索引来描述像素,这可以减小所有 Texture 的大小.因此,对于每个红色像素,您将有一个1"而不是#FF0000",并且在文件中的某处您有一个1=#FF0000".如果我们随后在 TextureAtlas 中将带有颜色索引的.gif"文件打包,那么索引会丢失并恢复默认的 RGB 颜色还是会产生问题?

Another little question:
With Gimp (and maybe a few other programs) you can use color indexes for ".gif" files. This reduces the size of all your Textures by saving an index for every color in the file and then using this index to describe the pixels. So for every red pixel you would have a "1" instead of "#FF0000" and somewhere in the file you have a "1=#FF0000". If we then pack the ".gif" files with the color indexes inside a TextureAtlas, is the index then lost and it restores the default RGB colors or will that make problems?

非常感谢!

推荐答案

我在使用相同纹理生成随机颜色的武器时遇到了同样的问题.

I faced the same Issue for generating weapon with random colors using the same texture.

所以我写了这个.
基本上,我会为您要编辑的纹理制作像素图.

So I wrote this.
Basically I make a pixmap of the texture you want to edit.

然后你迭代所有的像素,在迭代的同时我检查某些颜色,这些颜色是纹理的特定部分.(我建议使用不同深浅的灰色,因为 RGB 是相同的)

然后,当它位于需要更改颜色的像素上时,我使用颜色选择器方法为这些像素组获取颜色,该方法基本上是随机的,从预制颜色数组中获取颜色,
然后将该特定像素更改为新颜色.

Then you iterate over all of the pixels, while iterating I check for certain colors which are a part specific part of the texture. (I suggest using different shades of gray since the RGB is the same)

Then when it is on a pixel where the color needs to be changed I grab a color for those pixel groups using a color picker method which is basically random which gets a color from a prefabbed color array,
and then changes that specific pixel to the new color.

/**
 * Requires a asset's textureName, and requires gray scale colors of the
 * parts
 * 
 * @param texturename
 * @param colorBlade
 * @param colorEdge
 * @param colorAffinity
 * @param colorGrip
 * @return
 */
private static Texture genTexture(String texturename, int colorBlade,
        int colorEdge, int colorAffinity, int colorGrip, int colorExtra) {
    Texture tex = Game.res.getTexture(texturename);

    TextureData textureData = tex.getTextureData();
    textureData.prepare();

    Color tintBlade = chooseColor(mainColors);
    Color tintEdge = new Color(tintBlade.r + 0.1f, tintBlade.g + 0.1f,
            tintBlade.b + 0.1f, 1);

    Color tintAffinity = chooseColor(affinityColors);
    Color tintGrip;
    Color tintExtra = chooseColor(extraColors);

    boolean colorsAreSet = false;

    do {
        tintGrip = chooseColor(mainColors);

        if (tintAffinity != tintBlade && tintAffinity != tintGrip
                && tintGrip != tintBlade) {
            colorsAreSet = true;
        }
    } while (!colorsAreSet);

    Pixmap pixmap = tex.getTextureData().consumePixmap();

    for (int y = 0; y < pixmap.getHeight(); y++) {
        for (int x = 0; x < pixmap.getWidth(); x++) {

            Color color = new Color();
            Color.rgba8888ToColor(color, pixmap.getPixel(x, y));
            int colorInt[] = getColorFromHex(color);

            if (colorInt[0] == colorBlade && colorInt[1] == colorBlade
                    && colorInt[2] == colorBlade) {
                pixmap.setColor(tintBlade);
                pixmap.fillRectangle(x, y, 1, 1);
            } else if (colorInt[0] == colorEdge && colorInt[1] == colorEdge
                    && colorInt[2] == colorEdge) {
                pixmap.setColor(tintEdge);
                pixmap.fillRectangle(x, y, 1, 1);
            } else if (colorInt[0] == colorAffinity
                    && colorInt[1] == colorAffinity
                    && colorInt[2] == colorAffinity) {
                pixmap.setColor(tintAffinity);
                pixmap.fillRectangle(x, y, 1, 1);
            } else if (colorInt[0] == colorGrip && colorInt[1] == colorGrip
                    && colorInt[2] == colorGrip) {
                pixmap.setColor(tintGrip);
                pixmap.fillRectangle(x, y, 1, 1);
            }
            else if (colorInt[0] == colorExtra && colorInt[1] == colorExtra
                && colorInt[2] == colorExtra) {
            pixmap.setColor(tintExtra);
            pixmap.fillRectangle(x, y, 1, 1);
            }
        }
    }

    tex = new Texture(pixmap);
    textureData.disposePixmap();
    pixmap.dispose();

    return tex;
}

我希望这会有所帮助.
请不要只是复制粘贴,请尝试重新构建它以满足您的需求,否则您将学不到任何东西.

I hope this helps.
Please don't just copy paste, try to rebuild this to suit your needs or you won't learn anything.

相关文章