I want to ease a value overtime, for example I have the number 85, I want to ease it to 180 slow / fast depending on a certain delay, here's a visual example:
TIME: 0sec 0.25sec 0.5sec 0.75sec 1sec
VALUE: 85 100 126 140 180
What I know I need is System.currentTimeMillis()
, however I do not know how to use it properly to determine what is the next value in the next millisecond
I am trying to implement is a easing method to yaw and pitch within Minecraft so it is not just an instant yaw and pitch change.
If you need any other info, feel free to ask.
Code I tried:
public void easeValue(int delay) {
oldValue = (float) Math.ceil((System.currentTimeMillis() + delay) / oldValue);
if (oldValue >= targetValue) {
System.out.println("target reached");
}
}
( I had no idea what I was doing )
One problem with System.cTM
is that it changes as your clock setting changes. This does happen - usually servers and computers alike run NTP daemons which check current time against networked time servers and will adjust if need be. Ordinarily, daylight savings or switching time zones should not affect it, though, and good NTP daemons will smear changes out which means your easing will simply be slow or fast, instead of completely crash.
Nevertheless, one easy way out is to use System.nanoTime
instead which is more or less 'CPU uptime' (I'm oversimplifying), and isn't affected whatsoever by any time daemons or by the user changing the time by hand.
One small complication is that nanoTime can overflow, and you'll need to take that into consideration.
Your snippet doesn't take into account any notion of a 'start point'. You can't write a formula to calculate where you are along the linear progression from 85 to 180 unless you know at what point in time '85' ought to be returned, and at what point '180'. The method can therefore obviously never be just ease(int delay)
. You need to store the 'start and end' numbers (85 and 180 in your example) someplace, and the same applies to the start and end time, which need to be turned into absolute numbers at some moment in time (when you want the easing to start). It's java, so let's do what java is good at, and make an object to represent this state.
Here's a basic idea:
import java.util.concurrent.TimeUnit;
public class Easing {
private final long duration; // in nanos
private final long startTime;
private final long endTime;
private final int startValue;
private final int endValue;
private Easing(long duration, int startValue, int endValue) {
if (duration < 1) throw new IllegalArgumentException("duration not positive");
this.duration = duration;
this.startTime = System.nanoTime();
this.endTime = this.start + duration;
this.startValue = startValue;
this.endValue = endValue;
}
public static Easing ofSeconds(int seconds, int startValue, int endValue) {
return new Easing(TimeUnit.SECONDS.toNanos(seconds), startValue, endValue);
}
public int getCurrentValue() {
long now = System.nanoTime();
long delta = now - startTime;
long range = endTime - startTime;
if (delta > range) return endValue;
double p = 1.0 * delta / range;
int valRange = endValue - startValue;
return (int) (0.5 + (p * valRange) + startValue);
}
}
Let's see it in action:
public static void main(String[] args) throws Exception {
Easing easing = Easing.ofSeconds(10, 80, 180);
long start = System.currentTimeMillis();
for (int i = 0; i < 55; i++) {
long mark = System.currentTimeMillis();
System.out.printf("At [%d]: %d\n", mark - start, easing.getCurrentValue());
Thread.sleep(200);
}
}
At [0]: 80
At [229]: 82
At [430]: 84
At [633]: 86
At [839]: 88
At [1042]: 90
At [1244]: 92
At [1448]: 94
At [1651]: 97
At [1856]: 99
At [2060]: 101
At [2265]: 103
At [2468]: 105
At [2673]: 107
At [2878]: 109
At [3080]: 111
At [3284]: 113
At [3489]: 115
At [3693]: 117
At [3897]: 119
At [4101]: 121
At [4306]: 123
At [4510]: 125
At [4715]: 127
At [4919]: 129
At [5125]: 131
At [5329]: 133
At [5531]: 135
At [5735]: 137
At [5937]: 139
At [6139]: 141
At [6342]: 143
At [6544]: 145
At [6749]: 147
At [6952]: 150
At [7156]: 152
At [7361]: 154
At [7565]: 156
At [7770]: 158
At [7975]: 160
At [8178]: 162
At [8380]: 164
At [8581]: 166
At [8785]: 168
At [8986]: 170
At [9188]: 172
At [9392]: 174
At [9595]: 176
At [9797]: 178
At [10002]: 180
At [10207]: 180
At [10411]: 180
At [10613]: 180
At [10814]: 180
At [11019]: 180