问题
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
. 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
?
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 Texture
s 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?
Thanks a lot!
回答1:
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)
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.
回答2:
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.
Now you would only have to switch between indexes.
Another way to do it is with 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.
You can also do this with the Sprite class with the setColor function.
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.
回答3:
Rose Blax did really a good work. 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...
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. Are you ready? :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. The t-short may be in the same pack or not. But keep a hole between then to put the t-shirt in the future.
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.
3 - You will draw they both, but not same TextureRegion, your code will look like that:
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);
}
来源:https://stackoverflow.com/questions/24034352/libgdx-change-color-of-texture-at-runtime