Libgdx меняет цвет текстуры во время выполнения

в игре, созданной с помощью Libgdx у меня есть TextureAtlas, в котором я храню все TextureRegion для моих Animation из Player. Player по умолчанию имеет синюю футболку (например).
Теперь я хотел бы иметь более одного Player и каждый Player должен иметь другой цвет футболки.
Итак, в основном я хочу заменить синий на красный для второго Player, с зеленым для третьего Player и т. Д.
Я уверен, что смогу сделать это с PixMap, но не потеряю ли я тогда преимущество TextureAtlas
Есть ли другая возможность сделать это? Или мне нужно иметь каждую «цветную версию» в виде TextureRegion в TextureAtlas?
Еще один маленький вопрос:
С Gimp (и, возможно, несколькими другими программами) вы можете использовать цветовые индексы для файлов .gif.
Это уменьшает размер всех ваших Texture, сохраняя индекс для каждого цвета в файле и затем используя этот индекс для описания пикселей , Таким образом, для каждого красного пикселя у вас будет «1» вместо «# FF0000», а где-то в файле у вас будет «1 = # FF0000».
Если затем упаковать файлы «.gif» с цветовыми индексами в TextureAtlas, индекс потеряется и восстановит RGB по умолчанию цвета или это создаст проблемы?

Большое спасибо!

7 голосов | спросил Springrbua 4 J0000006Europe/Moscow 2014, 13:56:22

3 ответа


0

Я столкнулся с той же проблемой при создании оружия со случайными цветами с использованием той же текстуры.

Итак, я написал это.
В основном я делаю растровое изображение текстуры, которую вы хотите редактировать.

Затем вы выполняете итерации по всем пикселям, а при итерации я проверяю наличие определенных цветов, которые являются частью определенной части текстуры. (Я предлагаю использовать разные оттенки серого, так как RGB одинаков)

Затем, когда он находится на пикселе, где цвет должен быть изменен, я выбираю цвет для этих групп пикселей, используя метод выбора цвета, который в основном случайный, который получает цвет из готовой цветовой матрицы,
а затем изменяет этот конкретный пиксель на новый цвет.

/**
 * 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;
}

Надеюсь, это поможет.
Пожалуйста, не копируйте пасту, попробуйте перестроить ее так, чтобы она соответствовала вашим потребностям, иначе вы ничего не узнаете.

ответил Rose Blax 6 J0000006Europe/Moscow 2014, 12:55:17
0

Чтобы сделать это, просто установите максимальное количество игроков, сделайте футболки для всех, а также упаковайте их с атласом текстуры и добавьте их в один массив TextureRegion.

Теперь вам нужно будет только переключаться между индексами.

Еще один способ сделать это с помощью batch.setColor

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

И просто установите цвет партии спрайтов для каждой нарисованной вами футболки, а после того, как вы нарисовали все из них, снова установите цвет спрайта в белый.

Вы также можете сделать это с помощью класса Sprite с помощью функции setColor.

Если ваши футболки не очень большого размера, а максимальное количество игроков невелико, я бы порекомендовал первый способ.

ответил Boldijar Paul 4 J0000006Europe/Moscow 2014, 15:26:53
0

Rose Blax проделала отличную работу. Но если вам нужен способ сделать это с помощью SpriteBatch или для кого-то, кто имеет ту же проблему, но не хочет использовать Pixmap ...

Конечно, мне действительно нравится использовать Pixmap, но я видел, что использование «spritebatch /sprite.setcolor (r, g, b, a)» дало некоторые проблемы, так как изменил цвет всей текстуры вместо только футболки. .. Вот почему я пришел сюда и да, таким образом можно поменять только футболку. Вы готовы? : D

1 - Сделайте так, чтобы деталь захотела закрасить серым или белым 2 - Разделение частей приведет к окрашиванию в текстурном пакете или другой текстуре: в случае футболки вам понадобится пакет, в котором футболка вышла из вашего чара ... Да, будет кто-то с головой, руками и только ноги. Футболка может быть в одной упаковке или нет. Но оставьте дыру между ними, чтобы положить футболку в будущем.

это будет выглядеть так:

проверить этот ресурс

Не нужно бояться. Я знаю, что изображение разделено на весь характер, но если вы хотите заменить только футболку, то вы отделите только ее от остального тела.

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);
    }
ответил Play Marques 3 PM000000100000002431 2018, 22:54:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132