Fixing libGDX issue on iOS version with Landscape orientation

I’m currently working on a platform game made with libGDX-1.9.3. This game runs in Landscape mode.

Rainbow Diamonds screenshot
Rainbow Diamonds screenshot

The iOS compilation has worked right, and the tests on the iPhone simulator (with iOS 9) are also OK. But, when I test the game in my iPhone 4 with iOS 7, I find an error with touch event listeners. Touch events are received as if the phone were in Portrait mode instead of Landscape mode.

After searching some info about it, it seems this a known bug of libGDX, introduced in the version 1.9.0, and affect to iOS 7 and 8. You can follow the state of this issue on libGDX official site. On the issue page there is a workaround to fix the problem until it is resolved on libGDX distribution.

If is useful for you, next I put the code I use to temporarily fix this issue.

 

Knowing the iOS version of the device

We do this in the iOS app launcher, class IOSLauncher of the project MyGdxGame-ios. Here we check if our game is running on an iOS 7 or 8 device. The result is stored on a static boolean variable, that we can read on any point of our app.

...
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);
    }
    ...
}

 

Applying coordinates transformation

Now that we know if the device has iOS 7 or 8, the next thing is to translate the received coordinates when this condition is true. About this, some considerations:

  • It’s needed to make the transformation on all InputProcessor we use. Remember that if you use Stage, this class is also an implementation of InputProcessor. It’s not necessary to make the coordinates translation on each event listener we have, but only on the InputProcessor and it will do the event propagation with the right coordinates.
  • We must override the methods touchDown(), touchUp() and touchDragged() accordingly the methods we use in our event listeners. If you are not sure which methods you use, you can override them all.
  • If it’s used Touchpad as game input control, then it’s needed to overwrite the three methods in order to make the touchpad works succesfully.

The coordinates transformation han been taken from the libGDX issue page and it should be noted that there are two landscape orientation modes: LandscapeLeft (home button on left side) and LandscapeRight (home button on right side). To know which the current orientation is, it’s checked the device rotation, because the transformation differs on each case.

...
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);
    }
    ...
}

The previous fragment of code correspond to the method touchDown(). The methods touchUp() and touchDragged() are equals, but in the last line calling to the corresponding superclass method.

Regards!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*