简体   繁体   English

Libgdx在运行时更改Texture的颜色

[英]Libgdx change color of Texture at runtime

In a game made with libgdx I have a TextureAtlas in which I have stored all the TextureRegion s for my Animation s of the Player . 在用libgdx制作的游戏中,我有一个TextureAtlas ,我在其中存储了所有的TextureRegion用于我的Player Animation The Player by default has a blue T-Shirt (for example). 默认情况下, Player有一个蓝色T恤(例如)。 Now I would like to be able to have more then one Player and each should have another T-Shirt color. 现在我希望能够拥有一个以上的Player ,每个Player都应该拥有另一种T恤颜色。 So basically, I want to replace the blue with red for the second Player and with green for the 3rd Player and so on. 所以基本上,我想用红色来代替蓝色为第二个Player ,并与绿色为第三Player等。 I am sure I can do this with PixMap but wouldn't. 我相信我可以用PixMap做到这一点,但不会。 Because then I lose the advantage of the TextureAtlas (?). 因为那时我失去了TextureAtlas (?)的优势。 Is there another way to do this? 还有另一种方法吗? Or do I need to have every "color version" as a TextureRegion in the TextureAtlas ? 或者,我需要有充分的“色版”作为TextureRegionTextureAtlas

Another little question: 另一个小问题:
With Gimp (and maybe a few other programs) you can use color indexes for ".gif" files. 使用Gimp(可能还有一些其他程序),您可以使用“.gif”文件的颜色索引。 This reduces the size of all your Texture s by saving an index for every color in the file and then using this index to describe the pixels. 通过为文件中的每种颜色保存索引,然后使用此索引描述像素,可以减小所有Texture的大小。 So for every red pixel you would have a "1" instead of "#FF0000" and somewhere in the file you have a "1=#FF0000". 因此,对于每个红色像素,您将拥有“1”而不是“#FF0000”,并且文件中的某处有“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? 如果我们然后在TextureAtlas打包带有颜色索引的“.gif”文件,那么索引是否会丢失并恢复默认的RGB颜色或会产生问题?

Thanks a lot! 非常感谢!

A way of making this is just setting a maximum number of players, and make T-shirts for everyone, and pack them with texture atlas and add them into one TextureRegion array. 一种方法是设置最大数量的玩家,并为每个人制作T恤,并用纹理图集打包并将它们添加到一个TextureRegion数组中。

Now you would only have to switch between indexes. 现在您只需要在索引之间切换。

Another way to do it is with batch.setColor 另一种方法是使用batch.setColor

void    setColor(Color tint)
void    setColor(float color) 
void    setColor(float r, float g, float b, float a) 

And just set the color of the sprite batch for every T-Shirt you draw, and after you drawn all of them, put the spritebatch color to white again. 只需为您绘制的每个T恤设置精灵批次的颜色,并在绘制完所有T-Shirt后再将spritebatch颜色再次设置为白色。

You can also do this with the Sprite class with the setColor function. 您也可以使用带有setColor函数的Sprite类来完成此操作。

If your T-Shirts doesn't have a very big size, and your maximum player number is a small one, I would recommend the first method. 如果你的T恤没有很大的尺码,并且你的最大球员数量很小,我会推荐第一种方法。

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. 基本上我制作了你想要编辑的纹理的像素图。

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) (我建议使用不同的灰度,因为RGB是相同的)

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. 请不要只是复制粘贴,尝试重建它以满足您的需求,否则您将无法学到任何东西。

Rose Blax did really a good work. Rose Blax做得非常好。 But if you want a way to do that by using SpriteBatch or for someone who has same issue but does not want to use Pixmap... 但是如果你想通过使用SpriteBatch或者那些有相同问题但又不想使用Pixmap的人来做到这一点...

For sure I really like to use Pixmap, but I have seen the usage of "spritebatch/sprite.setcolor(r,g,b,a)" gave some challenges as change all texture color instead only the t-shirt... That's why I came here and yes, it's possible to change only the t-shirt using this way. 当然我真的很喜欢使用Pixmap,但我已经看到“spritebatch / sprite.setcolor(r,g,b,a)”的用法给了一些挑战,因为改变所有的纹理颜色而不只是T恤......那是为什么我来到这里是的,可以用这种方式改变T恤。 Are you ready? 你准备好了吗? :D :d

1 - Make the part want to paint grey scale or white 2 - Split the parts would paint in the texturepack or a different texture: in case of a t-shirt, you need a pack where the t-shirt is out of your char... Yes, will be someone with head, arms and legs only. 1 - 让部件想要绘制灰度或白色2 - 拆分部件会在纹理包中涂上或涂上不同的纹理:如果是T恤,你需要一个T恤不在你的字符中的包。 ..是的,只有头部,手臂和腿部的人。 The t-short may be in the same pack or not. t-short可以在同一包装中。 But keep a hole between then to put the t-shirt in the future. 但是在此之间保持一个洞,以便将T恤放在未来。

it will look like that: 它看起来像那样:

Check out this asset 看看这个资产

Do not need to be scared. 不需要害怕。 I know that image has splited whole characther, but If you want to change only the t-shirt then you will split only it from rest of body. 我知道图像已经分裂了整个字符,但是如果你只想改变T恤,那么你只会将它从身体的其他部分分开。

3 - You will draw they both, but not same TextureRegion, your code will look like that: 3 - 您将绘制它们,但不是相同的TextureRegion,您的代码将如下所示:

public void draw(SpriteBatch batch){
        //First we draw the player with a hole in his body
        batch.draw(playerA,0,0,75,100);
        //Here we set the color of next texture to be drawn as RED.
        batch.setColor(Color.RED);
        //Now we draw the t-shirt of the player in same x and half y.
        //That t-short has to be drawn in right position. That's why calc it.
        batch.draw(tshirtA, 0,50,50);
        //For don't affect others textures then make it white back.
        batch.setColor(Color.WHITE);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM