libgdx - Fondo Parallax embaldosado imperfectamente
(1)
Tengo algunos problemas con mis imágenes de fondo de paralaje. Inserté un GIF debajo que muestra los problemas: (1) hay una línea parpadeante negra en el borde de la textura y (2) el movimiento no es uniforme (y esto no se debe a la pequeña velocidad de cuadro del GIF). También agregué el código corto para mi clase ScrollableImage
, que está en el corazón de cómo implementé Parallax. Sospeché que el problema podría deberse a la operación de módulo dentro del método setScrollOffset
, pero eso no fue así y ahora me he quedado sin ideas. ¿Qué debo intentar solucionar este problema?
public class ScrollableImage extends Widget {
private TextureRegion region;
private float scrollOffset = 0.0f;
public ScrollableImage(TextureRegion region) {
this.region = region;
}
@Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
float w = region.getRegionWidth();
float h = region.getRegionHeight();
float scale = getHeight() / h;
float scaledWidth = w * scale;
float scaledHeight = h * scale;
float scaledOffset = scrollOffset * scale;
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
for (float x = getX() - scaledOffset; x < getX() + getWidth(); x += scaledWidth) {
batch.draw(region, x, getY(), scaledWidth, scaledHeight);
}
}
public float getScrollOffset() {
return scrollOffset;
}
public void setScrollOffset(float value) {
scrollOffset = Math.max(0, value % (float)region.getRegionWidth());
}
}
Logré solucionar el problema. En caso de que alguien se encuentre con problemas similares en el futuro, esto es lo que hice. Con la solución que me dio problemas antes, estaba formando el fondo del software (tuve un bucle para el que estaba dibujando la textura varias veces); Lo que hice ahora y lo que funciona bien es usar GL_REPEAT
de OpenGL, que utilizará el hardware (la GPU) para repetir la textura. Aquí está mi código:
public class ParallaxWidget extends Widget implements Disposable {
private static final int LAYER_COUNT = 2;
private Texture[] textures = new Texture[LAYER_COUNT];
private float[] scrollFactors = new float[LAYER_COUNT];
private float[] scrollAmounts = new float[LAYER_COUNT];
public ParallaxWidget(String path0, float factor0, String path1, float factor1) {
scrollFactors[0] = factor0;
scrollFactors[1] = factor1;
scrollAmounts[0] = 0.0f;
scrollAmounts[1] = 0.0f;
textures[0] = new Texture(Gdx.files.internal(path0));
textures[1] = new Texture(Gdx.files.internal(path1));
textures[0].setWrap(TextureWrap.Repeat, TextureWrap.ClampToEdge);
textures[1].setWrap(TextureWrap.Repeat, TextureWrap.ClampToEdge);
}
@Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
for (int i = 0; i < LAYER_COUNT; ++i) {
drawLayer(batch, i);
}
}
@Override
public void dispose() {
for (Texture texture : textures) {
texture.dispose();
}
}
public void updateScroll(float value) {
for (int i = 0; i < LAYER_COUNT; ++i) {
scrollAmounts[i] = value * scrollFactors[i];
}
}
private void drawLayer(Batch batch, int index) {
float x = getX();
float y = getY();
float w = getWidth();
float h = getHeight();
float th = textures[index].getHeight();
float tw = textures[index].getWidth() * h / th;
float u = scrollAmounts[index] / tw;
float v = 1.0f;
float u2 = u + (w / tw);
float v2 = 0.0f;
batch.draw(textures[index], x, y, w, h, u, v, u2, v2);
}
}