{"id":611,"date":"2017-08-21T13:20:16","date_gmt":"2017-08-21T12:20:16","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=611"},"modified":"2017-08-22T13:04:52","modified_gmt":"2017-08-22T12:04:52","slug":"solucion-de-error-en-libgdx-al-compilar-para-ios-con-orientacion-landscape","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/solucion-de-error-en-libgdx-al-compilar-para-ios-con-orientacion-landscape\/","title":{"rendered":"Soluci\u00f3n de error en libGDX al compilar para iOS con orientaci\u00f3n Landscape"},"content":{"rendered":"<p>Actualmente estoy trabajando en un videojuego de plataformas con libGDX-1.9.3. Este juego se ejecuta en modo apaisado o <em>Landscape<\/em>.<\/p>\n<figure id=\"attachment_612\" aria-describedby=\"caption-attachment-612\" style=\"width: 1014px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-612\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/08\/Captura-de-pantalla-2017-08-21-a-las-13.33.22.png\" alt=\"Captura Rainbow Diamonds\" width=\"1014\" height=\"560\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/08\/Captura-de-pantalla-2017-08-21-a-las-13.33.22.png 1014w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/08\/Captura-de-pantalla-2017-08-21-a-las-13.33.22-300x166.png 300w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/08\/Captura-de-pantalla-2017-08-21-a-las-13.33.22-768x424.png 768w\" sizes=\"(max-width: 1014px) 100vw, 1014px\" \/><figcaption id=\"caption-attachment-612\" class=\"wp-caption-text\">Captura Rainbow Diamonds<\/figcaption><\/figure>\n<p>La compilaci\u00f3n 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\u00f3n de las coordenadas de los escuchadores de eventos, porque se reciben como si el juego se estuviese ejecutando en posici\u00f3n vertical (<em>Portrait<\/em>).<\/p>\n<p>Tras buscar informaci\u00f3n en internet, parece que esto es un error conocido de libGDX, que se introdujo en la versi\u00f3n 1.9.0 y afecta a iOS 7 y 8. Pod\u00e9is seguir el estado de la incidencia en el <a href=\"https:\/\/github.com\/libgdx\/libgdx\/pull\/3590\" target=\"_blank\" rel=\"noopener\">sitio oficial de libGDX<\/a>. As\u00ed mismo, en la propia incidencia se da la forma de corregir el problema hasta que sea resuelto en la versi\u00f3n oficial de libGDX.<\/p>\n<p>Por si es de utilidad, a continuaci\u00f3n expongo el c\u00f3digo que yo utilizo como soluci\u00f3n temporal a este error.<\/p>\n<p>&nbsp;<\/p>\n<h3>Detecci\u00f3n de la versi\u00f3n de iOS del dispositivo<\/h3>\n<p>Esto lo haremos en el lanzador de la aplicaci\u00f3n para iOS, clase <code>IOSLauncher<\/code> del proyecto <em>MyGdxGame<\/em>-ios. Aqu\u00ed comprobaremos si el juego se est\u00e1 ejecutando sobre iOS 7 u 8, y almacenaremos el resultado en una variable est\u00e1tica booleana, que podremos consultar desde cualquier punto de nuestra aplicaci\u00f3n.<\/p>\n<pre lang=\"Java\">...\r\nimport org.robovm.apple.foundation.FoundationVersionNumber\r\n...\r\npublic class IOSLauncher extends IOSApplication.Delegate {\r\n\r\n    @Override\r\n    protected IOSApplication createApplication() {\r\n        \/\/ GameConfig.ios7or8 is a static boolean variable\r\n        GameConfig.ios7or8 = \r\n            FoundationVersionNumber.getVersion() >= FoundationVersionNumber.Version_iOS_7_0\r\n            && FoundationVersionNumber.getVersion() <= FoundationVersionNumber.Version_iOS_8_3;\r\n\r\n        IOSApplicationConfiguration config = new IOSApplicationConfiguration();\r\n        return new IOSApplication(new MyGdxGame(), config);\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Aplicar transformaci\u00f3n de coordenadas<\/h3>\n<p>Ahora sabemos cu\u00e1ndo el dispositivo donde se ejecuta el juego tiene iOS 7 u 8. Lo siguiente es transformar las coordenadas recibidas si se da esta condici\u00f3n. Sobre esto, dejo algunas recomendaciones:<\/p>\n<ul>\n<li>Es necesario hacer la transformaci\u00f3n en todos los <code>InputProcessor<\/code> que utilicemos. Recordad que si utilizamos <code>Stage<\/code>, esta clase tambi\u00e9n es una implementaci\u00f3n de <code>InputProcessor<\/code>. No es necesario sobrescribir cada escuchador de eventos que utilicemos, sino s\u00f3lo el m\u00e9todo base en el <code>InputProcessor<\/code> y ya se realizar\u00e1 la propagaci\u00f3n a los escuchadores con las coordenadas corregidas.<\/li>\n<li>Se deber\u00e1n sobrescribir los m\u00e9todos <code>touchDown()<\/code>, <code>touchUp()<\/code> y <code>touchDragged()<\/code> seg\u00fan los que utilicemos en nuestros escuchadores de eventos. Si no est\u00e1s seguro de cu\u00e1les necesitas, puedes sobrescribirlos todos.<\/li>\n<li>Si utilizas <code>Touchpad<\/code> como control en tu juego, entonces es necesario sobrescribir los tres m\u00e9todos anteriores para que el touchpad funcione correctamente.<\/li>\n<\/ul>\n<p>La transformaci\u00f3n de coordenadas ha sido tomada directamente de la incidencia de libGDX y, cabe destacar que se distinguen dos modos de apaisado: <em>LandscapeLeft<\/em> (bot\u00f3n home a la izquierda) y <em>LandscapeRight<\/em> (bot\u00f3n home a la derecha). Para conocer la orientaci\u00f3n actual se consulta la rotaci\u00f3n del dispositivo, ya que la transformaci\u00f3n de coordenadas es distinta en cada caso.<\/p>\n<pre lang=\"Java\">...\r\npublic class MyGameLayer extends WidgetGroup implements InputProcessor {\r\n    ...\r\n    @Override\r\n    public boolean touchDown(int screenX, int screenY, int pointer, int button) {\r\n        if (GameConfig.ios7or8) {\r\n            int rotation = Gdx.input.getRotation();\r\n            if (rotation == 90) { \/\/ Landscape right\r\n                int ox = screenX;\r\n                screenX = screenY;\r\n                screenY = Gdx.graphics.getHeight() - ox;\r\n            } else if (rotation == 270) { \/\/ Landscape left\r\n                int oy = screenY;\r\n                screenY = screenX;\r\n                screenX = Gdx.graphics.getWidth() - oy;\r\n            }\r\n        }\r\n        return super.touchDown(screenX, screenY, pointer, button);\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>El fragmento de c\u00f3digo anterior corresponde a la sobrescritura del m\u00e9todo <code>touchDown()<\/code>. Los m\u00e9todos <code>touchUp()<\/code> y <code>touchDragged()<\/code> ser\u00edan de la misma forma, y en la \u00faltima linea llamando al m\u00e9todo de la clase padre correspondiente.<\/p>\n<p>Saludos!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Actualmente estoy trabajando en un videojuego de plataformas con libGDX-1.9.3. Este juego se ejecuta en modo apaisado o Landscape. La compilaci\u00f3n para iOS ha funcionado correctamente, y en el simulador de iPhone, que ejecuta iOS 9, todo funciona perfectamente. Pero <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/solucion-de-error-en-libgdx-al-compilar-para-ios-con-orientacion-landscape\/\">Seguir leyendo <span class=\"screen-reader-text\">  Soluci\u00f3n de error en libGDX al compilar para iOS con orientaci\u00f3n Landscape<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":612,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[51,15],"language":[5],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/611"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=611"}],"version-history":[{"count":6,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/611\/revisions"}],"predecessor-version":[{"id":625,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/611\/revisions\/625"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media\/612"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=611"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}