问题
I am trying to convert android Canvas based game to Libgdx due to performance issues. Currently I am facing issues when I have to generate jigsaw puzzle piece sprites (dynamically).
What I did : I used android bitmap manipulation (Path and PorterDuff) and generated puzzle pieces and then fed that to Libgdx Game object in AndroidLauncher.
Question 1 : Is there a better way to convert a bitmap to puzzle pieces inside libgdx core project. (see below)
Question 2 : How can I create an area just to represent the puzzle piece. (bounding box or width/height based solution is not suitable), so that user can drag the piece when he/she only touches on that texture area.
Question 3 : Best way to detect when adjacent puzzle pieces are moved closer to each other by the user.
回答1:
Best Way to create a jigsaw puzzle game in LibGdx. There is an alternative to achieve pieces from an Image in LibGdx by using masking. Masking is achieved by creating a Shader Program i.e for this problem we have to write a 1.Vertex Shader 2.Fragment Shader 3.Create A Shader Program 4.create a custom sprite batch. for more info on shaders: https://github.com/libgdx/libgdx/wiki/Shaders
Shader Program looks like this: Below Vertex Shader For masking:-
Vertex Shader: Vertex shaders are responsible for performing operations on vertices.
` uniform mat4 u_projTrans;
attribute vec4 a_position; attribute vec4 a_color; attribute vec2 a_texCoord0; varying vec4 v_color; varying vec2 v_texCoord0; void main() { v_color = a_color; v_texCoord0 = a_texCoord0; gl_Position = u_projTrans * a_position; } `
2.Fragment Shader: A fragment shader functions in a very similar way to a vertex shader. But instead of processing it on a vertex it processes it once for each fragment.
`#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D u_texture;
uniform sampler2D u_mask;
varying vec4 v_color;
varying vec2 v_texCoord0;
void main()
{
vec4 texColor = texture2D(u_texture, v_texCoord0);
vec4 mask = texture2D(u_mask, v_texCoord0);
texColor.a *= mask.a;
gl_FragColor = v_color * texColor;
}`
create a Shader Program using Vertex and fragment Shader:
public class MyShader { private FileHandle fragmentShader = Gdx.files.internal("fragment.glsl"); private FileHandle vertexShader = Gdx.files.internal("vertex.glsl"); public ShaderProgram myShader = new ShaderProgram(this.vertexShader, this.fragmentShader); public MyShader () { this.myShader .begin(); this.myShader .setUniformi("u_texture", 0); this.myShader .setUniformi("u_mask", 1); this.myShader .end(); }
}
4.Custom Sprite Batch for Masking:
batch.setShader(MyShader.myShader);
this.alphaTexture.bind(1);
this.color.getTexture().bind(0);
batch.enableBlending();
Color c = getColor();
batch.draw(this.color, getX(), getY(), getOriginX(),
getOriginY(),
getWidth(), getHeight(), getScaleX(), getScaleY(), 0.0f);
batch.setShader(null);
ShaderLesson: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson2
来源:https://stackoverflow.com/questions/46271718/split-a-texture-into-puzzle-pieces-in-libgdx