Corona soporta varios modos de escalado para pasar lo que nosotros hemos "dibujado" en la pantalla virtual a la pantalla física del dispositivo:
- letterbox
- zoomEven
- zoomStretch
- none
No hace mucho, Corona introdujo un nuevo modo, el modo adaptive, que es adecuado para aplicaciones (este modo no tiene mucho sentido para los juegos). Vamos a verlo un poco en detalle.
Escalado simple
La forma más inmediata de hacer escalado es definir un tamaño fijo de pantalla (ancho x alto) en pixels virtuales, y situar nuestros objetos, texto e imágenes en esa pantalla virtual. Después se especifica un modo de escalado, por ejemplo "letterbox", que indica a Corona cómo rellenar la pantalla del dispositivo físico a partir del contenido de la pantalla virtual. El tamaño de la pantalla virtual lo podemos obtener con el API de Corona:
- display.contentWidth
- display.contentHeight
Esto es lo que ya habíamos visto en anteriores posts.
Tamaño de la pantalla virtual cambiante
El escalado simple funciona bien en muchas situaciones (por ejemplo en juegos), pero no es la solución en absolutamente todos los casos. El escalado simple tiene algunas desventajas:
- La relación de aspecto es fija (sea cual sea el dispositivo final), lo cual provoca franjas en los lados, como ya hemos visto
- Puede ocurrir que el escalado al dispositivo real no sea un número entero. Por ejemplo, si la pantalla virtual tiene un ancho de 320 y el dispositivo real tiene un ancho de 480, entonces cada pixel de la pantalla virtual tiene que traducirse a 1.5 pixels de la pantalla física. Esto lo hace Corona bastante bien, pero en algunas imágenes pueden notarse ciertas imperfecciones.
- Los widgets (botones, combos, etc) se verán escalados igual que el resto de los objetos. Lo cual provocará que en dispositivos como tablets veamos botones excesivamente grandes. Lo razonable sería que el tamaño de ciertos widgets fuera similar en todos los dispositivos, que no se escalaran por igual.
Estos problemas afectan fundamentalmente a las aplicaciones (no tanto a los juegos).
Una solución a estos problemas es que el tamaño de la pantalla virtual cambie en función del dispositivo. Esto es, que el tamaño de la pantalla virtual que definimos en config.lua tenga ancho y alto en función del tamaño del dispositivo. De esta forma se puede mantener la relación de aspecto del dispositivo (no franjas laterales) y escalar los pixels de forma perfecta (sin decimales).
Escalado adaptativo
Cambiar el tamaño de la pantalla virtual en función del dispositivo físico resuelve dos de los problemas mencionados anteriormente, pero no resuelve el problema del escalado proporcional de algunos widgets. Lo ideal sería que algunos widgets tuvieran el mismo tamaño "real" en todos los dispositivos.
El modo adaptativo de escalado resuelve todos estos problemas.
Principios
Cuando se selecciona el modo "adaptive" en config.lua, Corona calcula el ancho y el alto de la pantalla virtual mediante una serie de algoritmos. Los objetivos de estos algoritmos son:
- Debe mantenerse la relación de aspecto (sin franjas laterales)
- El escalado de pixels debe ser un número entero, o al menos, fracciones muy simples
- La densidad de pixels debe ser aproximadamente la misma en todos los dispositivos (la densidad de pixels mide el número de pixels que hay en cada pulgada de pantalla, si la densidad es similar, el tamaño de los widgets será el mismo en todos los dispositivos).
Desventajas
La primera (y creo que única) gran desventaja del modo adaptativo es que, como el tamaño de la pantalla virtual no es fijo, se complica bastante el desarrollo (sobre todo el posicionamiento y tamaño de los objetos en la pantalla). No podremos utilizar valores fijos para la posición y el tamaño de los objetos. Cada tamaño y posición se tendrán que calcular en función del ancho y alto de la pantalla virtual.
Escalado simple vs adaptativo
La diferencia entre el resultado entre estos dos modos se puede ver con un ejemplo sencillo. No voy a poner el código de la aplicación para evitar complicarnos la vida. Voy a poner dibujos sencillos para entender el problema.
Imaginemos una pantalla con una lista de elementos y un botón abajo:
En el escalado simple, los objetos serán más grandes (más centímetros) en un dispositivo más grande, proporcionalmente al tamaño de la pantalla (en todos los modos de escalado simple: letterbox, zoomEven, zoomStrech). Veamos esta aplicación en un iPhone4 y en un iPhone6 plus:
Se observa que el alto de cada fila es mayor (más centímetros) en el dispositivo grande. Sin embargo,tenemos el mismo número de filas en ambos dispositivos.
En el modo adaptativo los objetos tienen el mismo tamaño (aproximadamente) en todos los tamaños de dispositivo. Esto significa que en dispositivos con pantalla más grande dispondremos de más espacio para meter más elementos. Por ejemplo, se podrán visualizar más elementos en la lista.
En este caso, el alto de la fila en centímetros es el mismo en ambos dispositivos, y por tanto, se muestran más filas en el dispositivo grande.
Creo que con esta explicación se puede entender el modo de escalado adaptativo, que se puede resumir en:
- más complejo de programar (no se pueden utilizar coordenadas absolutas, ya que el tamaño de la pantalla virtual cambia en función del dispositivo)
- la relación de aspecto de la pantalla virtual es la misma que la del dispositivo
- el escalado se hace con números enteros (o fracciones muy simples)
- no hay franjas laterales
- si especificamos el tamaño de los widgets numéricamente (width=100), entonces el tamaño en centímetros es el mismo para todos los dispositivos
Y por último, no utilicéis el modo adaptativo para juegos, no merece la pena.