LibGDX:用于皮肤的ImageButton的色调图像

时间:2015-08-30 15:58:37

标签: java json libgdx

你好我想制作一个ImageButton,禁用的图像应该是灰色的。 我使用Skin和.json文件来定义它。是否有更好的方法来获得灰色的图像而不是复制所有图像并将它们添加到纹理包装器?

2 个答案:

答案 0 :(得分:4)

我认为实现这一目标的最佳方式(甚至唯一方法)是使用shaders。请注意shaders本身就是一个完整的主题,但是一旦掌握,或者甚至熟悉,就可以为你的游戏提供许多很酷的功能,比如灰度图像。

关于你的问题:首先需要的是着色器会影响你的图像(或者,在我们的例子中,ImageButton),这种着色器会将它们染成灰色。幸运的是,这些着色器已由其他人实现,作为similar question的答案。因此,如果我们从上面提取所需的着色器,我们有以下内容:

<强> grey.vsh:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;

varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
       vColor = a_color;
       vTexCoord = a_texCoord0;
       gl_Position =  u_projTrans * a_position;
}

<强> grey.fsh:

#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D u_texture;
uniform float grayscale;
void main() {
    vec4 texColor = texture2D(u_texture, vTexCoord);

    float gray = dot(texColor.rgb, vec3(0.96, 0.96, 0.96));
    texColor.rgb = mix(vec3(gray), texColor.rgb, grayscale);

    gl_FragColor = texColor * vColor;
}

假设这些文件位于assets文件夹中,我们可以创建一个ShaderProgram来编译和使用这些着色器:

ShaderProgram shader = new ShaderProgram(Gdx.files.internal("grey.vsh"), Gdx.files.internal("grey.fsh"));

现在我们可以扩展ImageButton,以便在我们希望它变灰时使用shader。在此示例中,ImageButton在单击时显示为灰色(或着色):

public class GreyedOutImageBtn extends ImageButton {
    private boolean isGreyedOut; // A flag that determines whther or not this should be greyed out
    public GreyedOutImageBtn(ImageButtonStyle style) {
        super(style);
        addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                // When clicked, toggle the grey effect
                Gdx.app.log("ClickListener", "Click");
                setIsGreyedOut(!getIsGreyedOut());
            }
        });
        isGreyedOut = false;
    }

    public boolean getIsGreyedOut() {
        return isGreyedOut;
    }

    public void setIsGreyedOut(boolean isGreyedOut) {
        this.isGreyedOut = isGreyedOut;
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        if (getIsGreyedOut()) {
            batch.end();
            batch.setShader(shader); // Set our grey-out shader to the batch
            batch.begin();
            super.draw(batch, parentAlpha); // Draw the image with the greyed out affect
            batch.setShader(null); // Remove shader from batch so that other images using the same batch won't be affected
        }
        else {
            // If not required to be grey-out, do normal drawing
            super.draw(batch, parentAlpha);
        }
    }
} 

这给出了以下结果。之前:

enter image description here

后:

enter image description here

在您更好地理解shaders之后,您可以根据自己的需要制作自己的内容。

答案 1 :(得分:1)

您可以使用ImageButtonStyle对象在已禁用的按钮上设置色调颜色,并使用newDrawable(Drawable drawable, Color tint)类中的Skin方法。

在代码中它可能看起来像这样。请注意,我们已使用纹理图集初始化了Skin对象,该纹理图集包含我们的UI纹理。有关详细信息,请参阅the wiki

// Create the tint color. Notice we use LibGDX Color class
Color tintColor = new Color(0.5f, 0.5f, 0.5f, 1f);

ImageButton.ImageButtonStyle btnStyle = new ImageButton.ImageButtonStyle();
btnStyle.up = skin.getDrawable("my_button");
btnStyle.disabled = skin.newDrawable("my_button", tintColor);

ImageButton myButton = new ImageButton(btnStyle);