Actualmente estoy trabajando en un videojuego de plataformas con libGDX-1.9.3. Este juego se ejecuta en modo apaisado o Landscape.

La compilación para iOS ha funcionado correctamente, y en el simulador de iPhone, que ejecuta iOS 9, todo funciona perfectamente. Pero al probar el juego en un iPhone 4 con iOS 7, se produce un error en la interpretación de las coordenadas de los escuchadores de eventos, porque se reciben como si el juego se estuviese ejecutando en posición vertical (Portrait).
Tras buscar información en internet, parece que esto es un error conocido de libGDX, que se introdujo en la versión 1.9.0 y afecta a iOS 7 y 8. Podéis seguir el estado de la incidencia en el sitio oficial de libGDX. Así mismo, en la propia incidencia se da la forma de corregir el problema hasta que sea resuelto en la versión oficial de libGDX.
Por si es de utilidad, a continuación expongo el código que yo utilizo como solución temporal a este error.
Detección de la versión de iOS del dispositivo
Esto lo haremos en el lanzador de la aplicación para iOS, clase IOSLauncher del proyecto MyGdxGame-ios. Aquí comprobaremos si el juego se está ejecutando sobre iOS 7 u 8, y almacenaremos el resultado en una variable estática booleana, que podremos consultar desde cualquier punto de nuestra aplicación.
... import org.robovm.apple.foundation.FoundationVersionNumber ... public class IOSLauncher extends IOSApplication.Delegate { @Override protected IOSApplication createApplication() { // GameConfig.ios7or8 is a static boolean variable GameConfig.ios7or8 = FoundationVersionNumber.getVersion() >= FoundationVersionNumber.Version_iOS_7_0 && FoundationVersionNumber.getVersion() <= FoundationVersionNumber.Version_iOS_8_3; IOSApplicationConfiguration config = new IOSApplicationConfiguration(); return new IOSApplication(new MyGdxGame(), config); } ... } |
Aplicar transformación de coordenadas
Ahora sabemos cuándo el dispositivo donde se ejecuta el juego tiene iOS 7 u 8. Lo siguiente es transformar las coordenadas recibidas si se da esta condición. Sobre esto, dejo algunas recomendaciones:
- Es necesario hacer la transformación en todos los
InputProcessorque utilicemos. Recordad que si utilizamosStage, esta clase también es una implementación deInputProcessor. No es necesario sobrescribir cada escuchador de eventos que utilicemos, sino sólo el método base en elInputProcessory ya se realizará la propagación a los escuchadores con las coordenadas corregidas. - Se deberán sobrescribir los métodos
touchDown(),touchUp()ytouchDragged()según los que utilicemos en nuestros escuchadores de eventos. Si no estás seguro de cuáles necesitas, puedes sobrescribirlos todos. - Si utilizas
Touchpadcomo control en tu juego, entonces es necesario sobrescribir los tres métodos anteriores para que el touchpad funcione correctamente.
La transformación de coordenadas ha sido tomada directamente de la incidencia de libGDX y, cabe destacar que se distinguen dos modos de apaisado: LandscapeLeft (botón home a la izquierda) y LandscapeRight (botón home a la derecha). Para conocer la orientación actual se consulta la rotación del dispositivo, ya que la transformación de coordenadas es distinta en cada caso.
... public class MyGameLayer extends WidgetGroup implements InputProcessor { ... @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { if (GameConfig.ios7or8) { int rotation = Gdx.input.getRotation(); if (rotation == 90) { // Landscape right int ox = screenX; screenX = screenY; screenY = Gdx.graphics.getHeight() - ox; } else if (rotation == 270) { // Landscape left int oy = screenY; screenY = screenX; screenX = Gdx.graphics.getWidth() - oy; } } return super.touchDown(screenX, screenY, pointer, button); } ... } |
El fragmento de código anterior corresponde a la sobrescritura del método touchDown(). Los métodos touchUp() y touchDragged() serían de la misma forma, y en la última linea llamando al método de la clase padre correspondiente.
Saludos!