package composition.effects;
import factories.Vectors;
import graphics.common.Vector;
import graphics.common.Velocity;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Freezerburn
*/
public class SlowingEffect implements Effect {
private Vector mVelDelta;
private Vector mMinimumSpeed;
// These are the minimum velocties that something can be reduced down to.
// They are static final to ensure that there is ALWAYS some predictable
// minimum velocity.
// Tweak these values as necessary during testing of the engine.
// Possibly make a set of variables that allow for customization of this?
private static final double X_MINIMUM = 1.0;
private static final double Y_MINIMUM = 1.0;
private static final double Z_MINIMUM = 1.0;
// This is the rate at which the velocity delta that is being applied is
// decayed. Simply, this makes it so that the closer something gets to its
// end location, the less drastic the slowing effect, so that it isn't taking
// a constant amount of velocity away each time this is called.
// This is toggleable through a method call or constructor. The default behavior
// applies the decay rate.
private static final double DEFAULT_DELTA_DECAY_RATE = 0.95;
private double mDeltaDecayRate;
private boolean mShouldApplyDecay;
// The amount of time it should take to either reach the end location, or
// to reach the minimum velocity.
private static final long DEFAULT_TIME = 300;
private long mTime;
public SlowingEffect( double xChange, double yChange, double zChange ) {
mVelDelta = Vectors.get( xChange, yChange, zChange );
mMinimumSpeed = Vectors.get( X_MINIMUM, Y_MINIMUM, Z_MINIMUM );
mDeltaDecayRate = DEFAULT_DELTA_DECAY_RATE;
mShouldApplyDecay = true;
mTime = DEFAULT_TIME;
}
public SlowingEffect( Vector changeOverTime ) {
mVelDelta = changeOverTime;
mMinimumSpeed = Vectors.get( X_MINIMUM, Y_MINIMUM, Z_MINIMUM );
mDeltaDecayRate = DEFAULT_DELTA_DECAY_RATE;
mShouldApplyDecay = true;
mTime = DEFAULT_TIME;
}
public SlowingEffect( Vector changeOverTime, Vector minimumSpeed ) {
mVelDelta = changeOverTime;
mMinimumSpeed = minimumSpeed;
mDeltaDecayRate = DEFAULT_DELTA_DECAY_RATE;
mShouldApplyDecay = true;
mTime = DEFAULT_TIME;
}
public void setMinimumSpeed( Vector minimumSpeed ) {
mMinimumSpeed.set( minimumSpeed );
}
public void setApplyDecayRate( boolean shouldApply ) {
mShouldApplyDecay = shouldApply;
}
public void setDecayRate( double decayRate ) {
mDeltaDecayRate = decayRate;
}
public void setTime( long time ) {
mTime = time;
}
@Override
public void applyTo( Effectable e, double delta ) {
EffectData data = e.getData();
if( data.isVelocitySupported() ) {
Velocity vel = data.getCurVelocity();
double modifier = mTime / delta;
double deltaDecay = mShouldApplyDecay ? mDeltaDecayRate : 1.0;
mVelDelta.modify( mVelDelta.getXPart() * modifier * deltaDecay,
mVelDelta.getYPart() * modifier * deltaDecay,
mVelDelta.getZPart() * modifier * deltaDecay );
vel.modify( mVelDelta.getXPart(), mVelDelta.getYPart(), mVelDelta.getZPart() );
// Make sure the modified velocity does not go below/above a certain amount
// so that something doesn't either reverse velocity, or slow down
// so much that it does not actually get to where it needs to go.
//TODO: Fix this so it works with both negative and positive velocities.
// currently it only works with positive, as minimumspeed will always
// be a positive value.
if( vel.getRealXVelocity() < mMinimumSpeed.getXPart() ) {
vel.setXVelocity( mMinimumSpeed.getXPart() );
}
if( vel.getRealYVelocity() < mMinimumSpeed.getYPart() ) {
vel.setYVelocity( mMinimumSpeed.getYPart() );
}
if( vel.getRealZVelocity() < mMinimumSpeed.getZPart() ) {
vel.setZVelocity( mMinimumSpeed.getZPart() );
}
vel = null;
}
data = null;
}
}