0
\$\begingroup\$

I am trying to write simple program which would get input from user by swiping in four capital directions.

I'm extending GestureDetector.java from libGDX and overriding fling method, but no matter how user swipes, velocityX and velocityY are positive values.

public boolean fling(float velocityX, float velocityY, int button){
            if(Math.abs(velocityX) < Math.abs(velocityY)) {
                if (velocityX > 0){
                    directionListener.onUp();
                } else {
                    directionListener.onDown();
                }
            }else{
                if (velocityY>0) {
                    directionListener.onRight();
                } else {
                    directionListener.onLeft();
                }
            }
}

Trying to get to the bottom of this I modified GestureDetector and for me the problem seems to be in VelocityTracker class:

static class VelocityTracker {
    int sampleSize = 10;
    float lastX, lastY;
    float deltaX, deltaY;
    long lastTime;
    int numSamples;
    float[] meanX = new float[sampleSize];
    float[] meanY = new float[sampleSize];
    long[] meanTime = new long[sampleSize];



    public void start (float x, float y, long timeStamp) {
        this.lastX = x;
        Gdx.app.log("Start()","lastX"+String.valueOf(lastX));
        lastY = y;
        deltaX = 0;
        deltaY = 0;
        numSamples = 0;
        for (int i = 0; i < sampleSize; i++) {
            meanX[i] = 0;
            meanY[i] = 0;
            meanTime[i] = 0;
        }
        lastTime = timeStamp;
    }

    public void update (float x, float y, long timeStamp) {
        long currTime = timeStamp;
        Gdx.app.log("update()","lastX : "+String.valueOf(this.lastX));
        deltaX = x - lastX;
        deltaY = y - lastY;
        Gdx.app.log("update()","x     : "+String.valueOf(x));

        lastX = x;
        lastY = y;
        long deltaTime = currTime - lastTime;
        lastTime = currTime;
        int index = numSamples % sampleSize;
        meanX[index] = deltaX;
        meanY[index] = deltaY;
        meanTime[index] = deltaTime;
        Gdx.app.log("update()","DeltaX: "+String.valueOf(deltaX));
        Gdx.app.log("--------------","---------------");
        numSamples++;
    }

    public float getVelocityX () {
        float meanX = getAverage(this.meanX, numSamples);
        float meanTime = getAverage(this.meanTime, numSamples) / 1000000000.0f;
        if (meanTime == 0) return 0;
        return meanX / meanTime;
    }

    public float getVelocityY () {
        float meanY = getAverage(this.meanY, numSamples);
        float meanTime = getAverage(this.meanTime, numSamples) / 1000000000.0f;
        if (meanTime == 0) return 0;
        return meanY / meanTime;
    }

    private float getAverage (float[] values, int numSamples) {
        numSamples = Math.min(sampleSize, numSamples);
        float sum = 0;
        for (int i = 0; i < numSamples; i++) {
            sum += values[i];
        }
        return sum / numSamples;
    }

    private long getAverage (long[] values, int numSamples) {
        numSamples = Math.min(sampleSize, numSamples);
        long sum = 0;
        for (int i = 0; i < numSamples; i++) {
            sum += values[i];
        }
        if (numSamples == 0) return 0;
        return sum / numSamples;
    }

    private float getSum (float[] values, int numSamples) {
        numSamples = Math.min(sampleSize, numSamples);
        float sum = 0;
        for (int i = 0; i < numSamples; i++) {
            sum += values[i];
        }
        if (numSamples == 0) return 0;
        return sum;
    }
}

It seems like lastX is set to 0 after update or start method are finished/started, output from log-ing is :

23459-23472/com.ssekav.myTestGame.android I/Start()﹕ lastX : 343.0 23472/com.ssekav.myTestGame.android I/TouchDragged﹕ 376.0:1402.0 23472/com.ssekav.myTestGame.android I/update()﹕ lastX : 0.0 23472/com.ssekav.myTestGame.android I/update()﹕ x : 376.0 23472/com.ssekav.myTestGame.android I/update()﹕ DeltaX: 376.0 23472/com.ssekav.myTestGame.android I/--------------﹕ --------------- 23472/com.ssekav.myTestGame.android I/TouchDragged﹕ 402.0:1388.0 23472/com.ssekav.myTestGame.android I/update()﹕ lastX : 0.0 23472/com.ssekav.myTestGame.android I/update()﹕ x : 402.0 23472/com.ssekav.myTestGame.android I/update()﹕ DeltaX: 402.0 23472/com.ssekav.myTestGame.android I/--------------﹕ --------------- 23472/com.ssekav.myTestGame.android I/TouchDragged﹕ 415.0:1383.0 23472/com.ssekav.myTestGame.android I/update()﹕ lastX : 0.0 23472/com.ssekav.myTestGame.android I/update()﹕ x : 415.0 23472/com.ssekav.myTestGame.android I/update()﹕ DeltaX: 415.0 23472/com.ssekav.myTestGame.android I/--------------﹕ ---------------

I feel like I am missing something basic here, however whole GestureDetection is exactly the same except for logging.

Edit: I Solved my problem with just moving deltaX and deltaY outside of VelocityTracker class, now it's working but I don't understand why it wouldn't work otherways.

\$\endgroup\$
6
  • \$\begingroup\$ Check out the LibGdx wiki page on this topic. \$\endgroup\$ Apr 30, 2015 at 23:58
  • \$\begingroup\$ I checked it out but it doesn't say if values are negative or positive, however I checked this link \$\endgroup\$
    – ssekav
    May 1, 2015 at 9:35
  • \$\begingroup\$ What are you doing in overridden version of GestureDetector? In most cases it's enough to just new up a GestureDetector and set that as the InputProcessor to get fling callbacks. \$\endgroup\$
    – bornander
    May 1, 2015 at 17:44
  • \$\begingroup\$ At first I followed this tutorial but it didn't work because of the velocityY/X values, I'm going to set up new project to see if problem still exists \$\endgroup\$
    – ssekav
    May 1, 2015 at 19:44
  • \$\begingroup\$ I don't have much experience with the GestureDetector, but if I find something I'll let you know. Also, please don't use code html tags, instead use the {} button (highlight your code first) to do code formatting. \$\endgroup\$ May 1, 2015 at 20:27

1 Answer 1

0
\$\begingroup\$

I know exactly what is the issue with your code even though you didn't post the part of code that caused the issue, because I had the exact same problem.

You must have instantiated the GestureDetector in the render() method, or any other subsequent method called in the render(), things like update(), handleInput() etc...

The result is that the gestureDetector is instantiated many times per second. It will still give you right X,Y, but anything related the deltaX, deltaY, velocity will be wrong.

This is because the last instantiated GestureDetector only knows the latest X,Y, and don't have records previous X,Y.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .