mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-10-12 09:56:33 +02:00
Die Methoden in `Validator` erwarten nun als zweiten Parameter den Namen des Parameters, der geprüft wird. Dadurch sollen die Methoden hilfreicher werden, indem geneuere Fehlermeldungen generiert werden können.
146 lines
3.5 KiB
Java
146 lines
3.5 KiB
Java
package schule.ngb.zm.anim;
|
|
|
|
import schule.ngb.zm.Constants;
|
|
import schule.ngb.zm.Updatable;
|
|
import schule.ngb.zm.util.Validator;
|
|
import schule.ngb.zm.util.events.EventDispatcher;
|
|
|
|
import java.util.function.DoubleUnaryOperator;
|
|
|
|
public abstract class Animation<T> extends Constants implements Updatable {
|
|
|
|
protected int runtime;
|
|
|
|
protected int elapsedTime = 0;
|
|
|
|
protected boolean running = false, finished = false;
|
|
|
|
protected DoubleUnaryOperator easing;
|
|
|
|
public Animation() {
|
|
this.runtime = Constants.DEFAULT_ANIM_RUNTIME;
|
|
this.easing = Constants.DEFAULT_EASING;
|
|
}
|
|
|
|
public Animation( DoubleUnaryOperator easing ) {
|
|
this.runtime = Constants.DEFAULT_ANIM_RUNTIME;
|
|
this.easing = Validator.requireNotNull(easing, "easing");
|
|
}
|
|
|
|
public Animation( int runtime ) {
|
|
this.runtime = runtime;
|
|
this.easing = Constants.DEFAULT_EASING;
|
|
}
|
|
|
|
public Animation( int runtime, DoubleUnaryOperator easing ) {
|
|
this.runtime = runtime;
|
|
this.easing = Validator.requireNotNull(easing, "easing");
|
|
}
|
|
|
|
public int getRuntime() {
|
|
return runtime;
|
|
}
|
|
|
|
public void setRuntime( int pRuntime ) {
|
|
this.runtime = pRuntime;
|
|
}
|
|
|
|
public DoubleUnaryOperator getEasing() {
|
|
return easing;
|
|
}
|
|
|
|
public void setEasing( DoubleUnaryOperator pEasing ) {
|
|
this.easing = pEasing;
|
|
}
|
|
|
|
public abstract T getAnimationTarget();
|
|
|
|
public final void start() {
|
|
this.initialize();
|
|
elapsedTime = 0;
|
|
running = true;
|
|
finished = false;
|
|
animate(easing.applyAsDouble(0.0));
|
|
initializeEventDispatcher().dispatchEvent("start", this);
|
|
}
|
|
|
|
public final void stop() {
|
|
running = false;
|
|
// Make sure the last animation frame was interpolated correctly
|
|
animate(easing.applyAsDouble((double) elapsedTime / (double) runtime));
|
|
this.finish();
|
|
finished = true;
|
|
initializeEventDispatcher().dispatchEvent("stop", this);
|
|
}
|
|
|
|
public void initialize() {
|
|
// Intentionally left blank
|
|
}
|
|
|
|
public void finish() {
|
|
// Intentionally left blank
|
|
}
|
|
|
|
public final void await() {
|
|
while( !finished ) {
|
|
Thread.yield();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isActive() {
|
|
return running;
|
|
}
|
|
|
|
@Override
|
|
public void update( double delta ) {
|
|
elapsedTime += (int) (delta * 1000);
|
|
if( elapsedTime > runtime )
|
|
elapsedTime = runtime;
|
|
|
|
double t = (double) elapsedTime / (double) runtime;
|
|
if( t >= 1.0 ) {
|
|
running = false;
|
|
stop();
|
|
} else {
|
|
animate(easing.applyAsDouble(t));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setzt den Fortschritt der Animation auf den angegebenen Wert.
|
|
* <p>
|
|
* {@code e} liegt in der Regel zwischen 0 und 1. Je nach verwendeten
|
|
* {@link Easing} Funktion kann der Wert aber in Ausnahmefällen unter 0 oder
|
|
* über 1 liegen. Die {@code step()} Methode muss dem nicht Rechnung tragen
|
|
* und kann wenn sinnvoll den {@code e} Wert auf [0, 1] limitieren:
|
|
* <pre><code>
|
|
* e = Constants.limit(e, 0, 1);
|
|
* </code></pre>
|
|
*
|
|
* @param e Fortschritt der Animation nachdem die Easingfunktion angewandt
|
|
* wurde.
|
|
*/
|
|
public abstract void animate( double e );
|
|
|
|
EventDispatcher<Animation, AnimationListener> eventDispatcher;
|
|
|
|
private EventDispatcher<Animation, AnimationListener> initializeEventDispatcher() {
|
|
if( eventDispatcher == null ) {
|
|
eventDispatcher = new EventDispatcher<>();
|
|
eventDispatcher.registerEventType("start", ( a, l ) -> l.animationStarted(a));
|
|
eventDispatcher.registerEventType("stop", ( a, l ) -> l.animationStopped(a));
|
|
}
|
|
return eventDispatcher;
|
|
}
|
|
|
|
public void addListener( AnimationListener listener ) {
|
|
initializeEventDispatcher().addListener(listener);
|
|
}
|
|
|
|
public void removeListener( AnimationListener listener ) {
|
|
initializeEventDispatcher().removeListener(listener);
|
|
}
|
|
|
|
}
|