rewrite VelocityTracker to work with varying frequency samples
- improve fling behaviour - should fix #49
This commit is contained in:
parent
6d3bc0caea
commit
a8f46fdd8d
@ -139,14 +139,17 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
|||||||
if (mStartMove < 0)
|
if (mStartMove < 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
mTracker.update(e.getX(), e.getY(), e.getTime());
|
||||||
|
|
||||||
float vx = mTracker.getVelocityX();
|
float vx = mTracker.getVelocityX();
|
||||||
float vy = mTracker.getVelocityY();
|
float vy = mTracker.getVelocityY();
|
||||||
|
|
||||||
/* reduce velocity for short moves */
|
/* reduce velocity for short moves */
|
||||||
float tx = e.getTime() - mStartMove;
|
float t = e.getTime() - mStartMove;
|
||||||
if (tx < FLING_THREHSHOLD) {
|
if (t < FLING_THREHSHOLD) {
|
||||||
vx *= tx / FLING_THREHSHOLD;
|
t = t / FLING_THREHSHOLD;
|
||||||
vy *= tx / FLING_THREHSHOLD;
|
vy *= t * t;
|
||||||
|
vx *= t * t;
|
||||||
}
|
}
|
||||||
doFling(vx, vy);
|
doFling(vx, vy);
|
||||||
return true;
|
return true;
|
||||||
@ -383,8 +386,7 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
|||||||
int w = Tile.SIZE * 3;
|
int w = Tile.SIZE * 3;
|
||||||
int h = Tile.SIZE * 3;
|
int h = Tile.SIZE * 3;
|
||||||
|
|
||||||
mMap.animator().animateFling(Math.round(velocityX),
|
mMap.animator().animateFling(velocityX, velocityY,
|
||||||
Math.round(velocityY),
|
|
||||||
-w, w, -h, h);
|
-w, w, -h, h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -398,105 +400,72 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
static class VelocityTracker {
|
||||||
* from libgdx:
|
/* sample window, 200ms */
|
||||||
* Copyright 2011 Mario Zechner <badlogicgames@gmail.com>
|
private static final int MAX_MS = 200;
|
||||||
* Copyright 2011 Nathan Sweet <nathan.sweet@gmail.com>
|
private static final int SAMPLES = 32;
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
******************************************************************************/
|
|
||||||
class VelocityTracker {
|
|
||||||
int sampleSize = 16;
|
|
||||||
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) {
|
private float mLastX, mLastY;
|
||||||
lastX = x;
|
private long mLastTime;
|
||||||
lastY = y;
|
private int mNumSamples;
|
||||||
deltaX = 0;
|
private int mIndex;
|
||||||
deltaY = 0;
|
|
||||||
numSamples = 0;
|
private float[] mMeanX = new float[SAMPLES];
|
||||||
for (int i = 0; i < sampleSize; i++) {
|
private float[] mMeanY = new float[SAMPLES];
|
||||||
meanX[i] = 0;
|
private int[] mMeanTime = new int[SAMPLES];
|
||||||
meanY[i] = 0;
|
|
||||||
meanTime[i] = 0;
|
public void start(float x, float y, long time) {
|
||||||
|
mLastX = x;
|
||||||
|
mLastY = y;
|
||||||
|
mNumSamples = 0;
|
||||||
|
mIndex = SAMPLES;
|
||||||
|
mLastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(float x, float y, long time) {
|
||||||
|
if (--mIndex < 0)
|
||||||
|
mIndex = SAMPLES - 1;
|
||||||
|
|
||||||
|
mMeanX[mIndex] = x - mLastX;
|
||||||
|
mMeanY[mIndex] = y - mLastY;
|
||||||
|
mMeanTime[mIndex] = (int) (time - mLastTime);
|
||||||
|
|
||||||
|
mLastTime = time;
|
||||||
|
mLastX = x;
|
||||||
|
mLastY = y;
|
||||||
|
|
||||||
|
mNumSamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getVelocity(float[] move) {
|
||||||
|
mNumSamples = Math.min(SAMPLES, mNumSamples);
|
||||||
|
|
||||||
|
double duration = 0;
|
||||||
|
double amount = 0;
|
||||||
|
|
||||||
|
for (int c = 0; c < mNumSamples; c++) {
|
||||||
|
int index = (mIndex + c) % SAMPLES;
|
||||||
|
|
||||||
|
float d = mMeanTime[index];
|
||||||
|
if (c > 0 && duration + d > MAX_MS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
duration += d;
|
||||||
|
amount += move[index] * (d / duration);
|
||||||
}
|
}
|
||||||
lastTime = timeStamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(float x, float y, long timeStamp) {
|
if (duration == 0)
|
||||||
long currTime = timeStamp;
|
|
||||||
deltaX = x - lastX;
|
|
||||||
deltaY = y - lastY;
|
|
||||||
lastX = x;
|
|
||||||
lastY = y;
|
|
||||||
long deltaTime = currTime - lastTime;
|
|
||||||
lastTime = currTime;
|
|
||||||
int index = numSamples % sampleSize;
|
|
||||||
meanX[index] = deltaX;
|
|
||||||
meanY[index] = deltaY;
|
|
||||||
meanTime[index] = deltaTime;
|
|
||||||
numSamples++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getVelocityX() {
|
|
||||||
float meanX = getAverage(this.meanX, numSamples);
|
|
||||||
float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
|
|
||||||
if (meanTime == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
return meanX / meanTime;
|
|
||||||
|
return (float) ((amount * 1000) / duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getVelocityY() {
|
public float getVelocityY() {
|
||||||
float meanY = getAverage(this.meanY, numSamples);
|
return getVelocity(mMeanY);
|
||||||
float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
|
|
||||||
if (meanTime == 0)
|
|
||||||
return 0;
|
|
||||||
return meanY / meanTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getAverage(float[] values, int numSamples) {
|
public float getVelocityX() {
|
||||||
numSamples = Math.min(sampleSize, numSamples);
|
return getVelocity(mMeanX);
|
||||||
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;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ public class Animator {
|
|||||||
animStart(duration, ANIM_SCALE);
|
animStart(duration, ANIM_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void animateFling(int velocityX, int velocityY,
|
public synchronized void animateFling(float velocityX, float velocityY,
|
||||||
int minX, int maxX, int minY, int maxY) {
|
int minX, int maxX, int minY, int maxY) {
|
||||||
|
|
||||||
if (velocityX * velocityX + velocityY * velocityY < 2048)
|
if (velocityX * velocityX + velocityY * velocityY < 2048)
|
||||||
@ -162,8 +162,7 @@ public class Animator {
|
|||||||
|
|
||||||
float duration = 500;
|
float duration = 500;
|
||||||
|
|
||||||
// pi times thumb..
|
float flingFactor = 0.5f;
|
||||||
float flingFactor = (duration / 2500);
|
|
||||||
mVelocity.x = velocityX * flingFactor;
|
mVelocity.x = velocityX * flingFactor;
|
||||||
mVelocity.y = velocityY * flingFactor;
|
mVelocity.y = velocityY * flingFactor;
|
||||||
clamp(mVelocity.x, minX, maxX);
|
clamp(mVelocity.x, minX, maxX);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user