在 libgdx 中将纹理拆分为拼图

2022-01-12 00:00:00 opengl-es android bitmap java libgdx

由于性能问题,我正在尝试将基于 android Canvas 的游戏转换为 Libgdx.目前,当我必须(动态)生成拼图碎片精灵时,我遇到了问题.

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).

我做了什么:我使用了 android 位图操作(Path 和 PorterDuff)并生成了拼图,然后将其提供给 AndroidLauncher 中的 Libgdx Game 对象.

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.

问题 1:有没有更好的方法将位图转换为 libgdx 核心项目中的拼图.(见下文)

Question 1 : Is there a better way to convert a bitmap to puzzle pieces inside libgdx core project. (see below)

问题 2:如何创建一个区域来代表拼图.(边界框或基于宽度/高度的解决方案不适合),这样用户可以在他/她仅触摸该纹理区域时拖动块.

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.

问题 3:检测相邻拼图何时被用户移近的最佳方法.

Question 3 : Best way to detect when adjacent puzzle pieces are moved closer to each other by the user.

推荐答案

在 LibGdx 中创建拼图游戏的最佳方式.有一种替代方法可以通过使用遮罩从 LibGdx 中的图像中获取片段.遮罩是通过创建一个着色器程序来实现的,即对于这个问题,我们必须编写一个1.顶点着色器2.片段着色器3.创建着色器程序4.创建自定义精灵批次.有关着色器的更多信息:https://github.com/libgdx/libgdx/wiki/Shaders

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:-

  1. 顶点着色器:顶点着色器负责对顶点执行操作.

  1. Vertex Shader: Vertex shaders are responsible for performing operations on vertices.

`统一 mat4 u_projTrans;

` 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:片段着色器的功能与顶点着色器非常相似.但是不是在顶点上处理它,而是为每个片段处理一次.

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;
}`

  1. 使用顶点着色器和片段着色器创建着色器程序:

  1. 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:

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

ShaderLesson: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson2

相关文章