Search code examples
androidlibgdxrotation

User Input works different on Android as on Desktop


I am making an simple game in Libgdx. The problem is that the code works fine on Desktop but not on Android (Galaxy S6). In the game you rotate with your finger around the center of the Device (width/2,height/2). The Point where you touch is recognized and the angle between this touchpoint and center will be calculated and saved in speicher1 (it is always between 0 and 360):

touchpoint.set(Gdx.input.getX(),Gdx.input.getY());
speicher1 = (float)((Math.atan2 (touchpoint.x - width/2, -(touchpoint.y - height/2))*180.0d/Math.PI))+180; //Touchpunkt Gradzahl zur Mitte

With this calculated angel you rotate a circle which is displayed on the screen. All this works fine on both (Desktop,Android). Now when you for example put your finger at 180° the circle immediatly rotate to this point. But thats not that what I want. Only when you move your finger it should rotate. So when you start touching anywhere the circle should not rotate, only when you start dragging. Hopefully I could make this clear to you :D. I made a solution for this:

    touchpoint.set(Gdx.input.getX(),Gdx.input.getY());
    speicher1 = (float)((Math.atan2 (touchpoint.x - width/2, -(touchpoint.y - height/2))*180.0d/Math.PI))+180; //Toucpunkt Gradzahl zur Mitte

    if (Gdx.input.justTouched()) {
        speicher2 = 360-(speicher1 - kcc.getCcdegreee());
    }
    speicher1 = speicher1 + speicher2;
    while (speicher1 >= 360) {
        speicher1 -= 360;
    }
    kcc.setCcdegreee(speicher1);

[kcc is my Class where every information of the Circle is saved in (Texture,size,position,angle(Ccdegree))]

I solved this problem with justTouched Method and than made the this point as 'Start Point'. Now comes the Problem, it works fine on Desktop but not on Android?!

Whole Code:

public void render(SpriteBatch sb, SpriteBatch textsb) {
    //Wenn getouched(gedreht wurde)
    if (Gdx.input.isTouched()) {
        handleInput();
    }

    sb.begin();
    //COLORCIRCLE
    sb.draw(kcc.getCc(),kcc.getCcposition().x,kcc.getCcposition().y,kcc.getCcwidth()/2,kcc.getCcwidth()/2,kcc.getCcwidth(),kcc.getCcheight(),1,1,-kcc.getCcdegreee(),true);
    sb.end();
}

[Render Method where I find out if display is touched and draw the Circle on screen with calculated angel]

Handle Input Method:

protected void handleInput() {
    touchpoint.set(Gdx.input.getX(),Gdx.input.getY());
    speicher1 = (float)((Math.atan2 (touchpoint.x - width/2, -(touchpoint.y - height/2))*180.0d/Math.PI))+180; //Toucpunkt Gradzahl zur Mitte
    if (Gdx.input.justTouched()) {
        speicher2 = 360-(speicher1 - kcc.getCcdegreee());
    }
    speicher1 = speicher1 + speicher2;
    while (speicher1 >= 360) {
        speicher1 -= 360;
    }
    kcc.setCcdegreee(speicher1);
}

As I said the whole thing works perfectly on Desktop but not on Android :/. I hope that someone has an solution for this or find my fault.


Solution

  • I would strongly suggest not directly polling the touchpoint, having to deal with justTouched() and all those things, but to use an InputProcessor or a GestureListener instead.

    This gives you event-based inputs which is far more flexible and easier to implement.

    Option1: InputProcessor

    When you implement this interface, you actually just need to use the

    public boolean touchDown (int x, int y, int pointer, int button) {
          return false;
       }
    
       public boolean touchUp (int x, int y, int pointer, int button) {
          return false;
       }
    
       public boolean touchDragged (int x, int y, int pointer) {
          return false;
       }
    

    methods. There, on touchDown you would just need to store the position of the touchdown event. In onDragged(), you would calculate the angle you have rotated by. Since the onDragged() is usually called quite frequently when dragging normally (each frame), you would end up with a lot of quite little delta angles which you can use to rotate the circle in you window centre.

    Option2: GestureListener

    Even more convenient it gets with a GestureListener, since this one already includes the delta to the last position, giving you everything you need to calculate the delta angle per frame.

    https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/input/GestureDetector.GestureListener.html#pan-float-float-float-float-

    I hope that helps... It should clearly simplify your logic and make your code much more readable and maintainable :)