[LibGDX] soporte múltiples resoluciones y densidades

Lecherito

Como muchos ya sabéis me propuse hacer un jueguecito con su editor de mapas, el caso es que me acabo de encontrar con este problema, el soportar más de una pantalla ya que no quiero que el juego tenga este obstáculo.

He seguido este tutorial: http://blog.gemserk.com/2013/02/13/our-solution-to-handle-multiple-screen-sizes-in-android-part-two/ y las cosas se ven bastante bien (escalan bien, que es lo que quería)

A raíz de este cambio me han aparecido 2 problemas:

Me pillé las 3 clases y todo bien, el problema es el siguiente: Ahora los actores de la stage no responden bien a los click, los actores se redimensionan (tengo una tabla para el menú principal por ejemplo) pero el "sitio" del click sigue siendo donde estaban antes, es como si no se estuviera coscando de que se ha redimensionado o algo.

Y segundo problema: el cálculo de espaciado entre actores, dado que en una pantalla va a tener más zoom, habrá más píxeles entre actores por lo que no sé, he leido sobre tener 1m = 30 pixeles por ejemplo pero no sé como adaptarlo a diferentes pantallas

AbstractScreen (De la que derivan todas las screen)

Código del menú: http://pastebin.com/9bRxSsHv (un ejemplo de cosa que se descuadra)

YaW

No deberías de cambiar el tamaño del Stage ni redimensionar actores. Lo más fácil es aplicar todo sobre la cámara y por lo tanto tu stage siempre medirá lo mismo (independientemente de lo que ocupe en pantalla) y tus actores, el espaciado y demás también.

Así es como lo hicimos en OMG vamos y funciona bastante bien.

2 respuestas
Lecherito

#2 Se aplica sobre el viewport, no? Tengo ahora mismo un lío de conceptos bastante grande xD Diría que es lo que estoy haciendo, el stage no lo cambio en ningún momento a mi parecer. Lo de los actores lo he pillado rápido pero lo de la cámara me está costando bastante

T

#2 Utilizáis distintos sprites para distintas densidades? No se os estiran las imágenes si alguien utiliza una resolución con mucho largo y poco ancho de esa manera? Estoy yo ahora con un menu pero si no redimensiono el stage los sprites se estiran.

1 respuesta
Lecherito

#4 Lol fail no iba para mi xDD

1 respuesta
T

#5 A ver yo lo que estoy haciendo y funciona en mi caso es fijar una longitud fija para el mapa y ajustar la altura dependiendo de la resolucion. Me explico, mi mapa esta compuesto por tiles cuadrados, yo digo que quiero mostrar siempre 10 tiles de largo entonces dependiendo de la resolucion y para mantener la proporción cuadrada de los tiles muestro mas o menos de alto pero siempre 10 a lo largo.

En mi caso funciona ya que el alto es el cielo y no me importa mostrar mas o menos cielo y lo importante en mi caso es que siempre se muestre la misma distancia a lo largo del mapa para que la experiencia sea la misma en distintos dispositivos. Del mismo modo se podría hacer mostrar un alto fijo y ya dependiendo de la resolución mostrar mas o menos de la longitud del mapa.

No se si se ha entendido, en cualquier caso en mi situación no utilizo stage dibujo directamente el mapa y la solución se adapta a lo que quiero hacer.

Ahora estoy intentando hacer lo mismo en el Menu Principal o buscar otra solución, aqui si que tengo un stage y lo que hago es:

float scaleFactor = 800/width; 

stage.setViewport(800 , height* scaleFactor , true); 

camera.setToOrtho(false,width,height);

Donde 800 seria el largo que he fijado. El problema es que si estira mucho los sprites se pixelan así que estoy planteándome usar distintos sprites para distintas densidades.

Si no cambio el tamaño del stage en mi caso los sprites se estiran dejando de ser cuadrados ademas de que el hitbox parece estar roto también incluso fuera de donde deberia.

Como ultima opción esta actualizar camara y stage con la resolucion actual sin ningun procesado, en mi caso la posicion la mantiene bien pero corro el riesgo de que si tiene mucha densidad la pantalla se muestren muy pequeños y si tengo poca se muestren muy grandes.

1 respuesta
YaW

Lo que yo comentaba es lo mismo que #6
En realidad lo que tenemos es un "ResizerStage" que extiende de Stage y entonces todas las UI dependen de este Stage especial y él ya internamente se dedica a hacer los zooms necesarios y demás.

Sobre lo que preguntas de los distintos assets nosotros en Oh My Goat si que lo hacemos, tenemos assets para SD, MD y HD. Partimos de un ancho fijo (854px) y según varios factores se eligen unos u otros assets. El HD se coge si el ancho es mayor que 854 x 1.45 y el SD lo ponemos a mano en móviles rancios que no soportan toda la carga en memoria de las texturas del MD.

1 1 respuesta
T

#7 Ok me lo temía, no hay nada que odie mas que tener que estar creando y empaquetando sprites XDD aunque lo dejare para el final que aun es todo susceptible de ser cambiado. Gracias por comentar

Ahora estoy intentando resucitar un xperia x8 para pruebas con una resolución de nada mas y nada menos que de 320 x 480!

Lecherito

Entonces aconsejáis quitar todo esas clases y simplemente con el setToOrtho y el setViewport se vería más o menos en todos los móviles? (Agrandando todo en los móviles con mayor resolución)

Esto de las cámaras, los viewport, el setToOrto, me tiene ya hartísimo, cuanto más leo más confundido estoy, lol

1 respuesta
T

#9 Yo al final lo que estoy haciendo para el menú principal es fijar una resolución de diseño, por ejemplo 800x600 (puedes fijarla a lo que quieras y no se que conviene mas si mas altas o mas pequeñas) y esa va a ser siempre la resolución de mi stage y la resolución de la cámara sera la que toque. Importante en stage.setViewport(800,600,true) poner a true el ultimo parámetro para que respete el aspectratio de los sprites.

De este modo lo que sucede es que si me voy a resoluciones mucho mas altas los sprites se veran pixelados ya que estan muy aumentados, en esos casos lo que tengo es otro spritesheet con sprites con mas resolución. Es un proceso chungo por que tengo que preparar sprites a varias resoluciones y empaquetarlos pero bueno para los botones del menú son pocos.

Este método me ha funcionado en el Xperia X8 con 320x480 (191 ppi) y en el Nexus 7 con 1280 x 800 (216 ppi), para mi es suficiente que funcione en dispositivos con pantallas tan diferentes.

1 respuesta
Lecherito

#10 Claro, si realmente es lo que quiero, no me importa que se vean pixelados la verdad por que las imágenes no las pongo yo, las pone el que crea el mapa.

Pero vamos, por más que pongo a true el setViewport nada cambia, la verdad es que estoy ya bastante hartito con este tema, es que no puede ser tan difícil xDD

Por ejemplo ayer creé un nuevo proyecto de libgdx e intenté hacerlo ahí y nada, o no se hace resize o no mantiene el ratio

spoiler
2 respuestas
T

#11 A ver, si la camara no la fijas a 800x600, solo el stage si que mantiene el tamaño pero se pixelan los sprites.

 
width = Gdx.graphics.getWidth();
height =Gdx.graphics.getHeight();

stage = new Stage(0, 0, true);
camera = new OrthographicCamera(width,height);
                
//stage.setCamera(camera); stage.setViewport(800, 600, true); camera.setToOrtho(false, width,height);

El problema es con el pixelado, me precipite al decir que era tan fácil como meter sprites a mas resolución para pantallas con mas resolución, ahí si que hace que el sprite salga mas grande y tendré que buscar una forma para escalar.

T

#11 Ya he descubierto la diferencia :palm: si quitas la linea stage.setCamera(camera); funciona como te digo que deberia, he actualizado el codigo en #12

Y bueno todo esto para el caso de una tabla no se como sera para todo.

1 respuesta
Lecherito

#13 Mil gracias, al final lo hice así, aunque ni te imaginas el problema que tenía xDDD

El caso es que yo estaba redimensionando la ventana en "live" y eso hacía que se fastidiaran las tablas que usaba, aunque si creabas el juego de una, todo iba perfecto, que asquerosidad, todo el trabajo casi para nada xD

1 respuesta
T

#14 Me alegro que lo solucionaras, yo al final también encontré una solución, primero por que estaba usando un filtro para los sprites que hacia que se vieran MUY pixelados cuando modificabas el tamaño, ya cuando lo cambie por Linear o MipMapLinear mejoro el asunto.

Al final en combinacion con eso y un stage wrapper donde metia mis imageButtons y los posicionaba y redimensionaba con valores absolutos sobre 800x600 (deje de usar table) consegui poder tener distintos sprites para altas resoluciones y ademas todo funcionaba genial.

No veas que odisea conseguir que funcionara como queria XD

1 respuesta
Lecherito

#15 Me miraré lo del filtro Linear que seguramente también lo necesite :P

Ahora me falta saber como realmente organizar las cosas xD

1 respuesta
T

#16 Pues míralo por que cambia mucho el tema se nota la diferencia una barbaridad y yo hasta ahora ni le había prestado atención a los filtros XD. También creo que en linear es mas lento pero de momento no estoy teniendo problemas de rendimiento

Suerte! XD

Usuarios habituales

  • Theta
  • Lecherito
  • YaW