2016-12-23 10:03:32 +01:00
|
|
|
package itdelatrisu.opsu.ui;
|
|
|
|
|
|
|
|
import itdelatrisu.opsu.GameImage;
|
|
|
|
import itdelatrisu.opsu.ui.animations.AnimatedValue;
|
|
|
|
import itdelatrisu.opsu.ui.animations.AnimationEquation;
|
|
|
|
|
|
|
|
import org.newdawn.slick.Image;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Star fountain consisting of two star streams.
|
|
|
|
*/
|
|
|
|
public class StarFountain {
|
|
|
|
/** The (approximate) number of stars in each burst. */
|
2016-12-23 22:53:12 +01:00
|
|
|
private static final int BURST_SIZE = 125;
|
2016-12-23 10:03:32 +01:00
|
|
|
|
|
|
|
/** Star streams. */
|
|
|
|
private final StarStream left, right;
|
|
|
|
|
|
|
|
/** Burst progress. */
|
2016-12-23 22:53:12 +01:00
|
|
|
private final AnimatedValue burstProgress = new AnimatedValue(1000, 0, 1, AnimationEquation.LINEAR);
|
|
|
|
|
|
|
|
/** The maximum direction offsets. */
|
|
|
|
private final float xDirection, yDirection;
|
|
|
|
|
|
|
|
/** Motion types. */
|
|
|
|
private enum Motion {
|
|
|
|
NONE {
|
|
|
|
@Override
|
|
|
|
public void init(StarFountain fountain) {
|
|
|
|
fountain.left.setDirection(0, fountain.yDirection);
|
|
|
|
fountain.right.setDirection(0, fountain.yDirection);
|
|
|
|
fountain.left.setDirectionSpread(20f);
|
|
|
|
fountain.right.setDirectionSpread(20f);
|
|
|
|
fountain.left.setDurationSpread(1000, 200);
|
|
|
|
fountain.right.setDurationSpread(1000, 200);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
OUTWARD_SWEEP {
|
|
|
|
@Override
|
|
|
|
public void init(StarFountain fountain) {
|
|
|
|
fountain.left.setDirectionSpread(0f);
|
|
|
|
fountain.right.setDirectionSpread(0f);
|
|
|
|
fountain.left.setDurationSpread(850, 0);
|
|
|
|
fountain.right.setDurationSpread(850, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void update(StarFountain fountain) {
|
|
|
|
float t = fountain.burstProgress.getValue();
|
|
|
|
fountain.left.setDirection(fountain.xDirection - fountain.xDirection * 2f * t, fountain.yDirection);
|
|
|
|
fountain.right.setDirection(-fountain.xDirection + fountain.xDirection * 2f * t, fountain.yDirection);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
INWARD_SWEEP {
|
|
|
|
@Override
|
|
|
|
public void init(StarFountain fountain) { OUTWARD_SWEEP.init(fountain); }
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void update(StarFountain fountain) {
|
|
|
|
float t = fountain.burstProgress.getValue();
|
|
|
|
fountain.left.setDirection(-fountain.xDirection + fountain.xDirection * 2f * t, fountain.yDirection);
|
|
|
|
fountain.right.setDirection(fountain.xDirection - fountain.xDirection * 2f * t, fountain.yDirection);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Initializes the streams in the fountain. */
|
|
|
|
public void init(StarFountain fountain) {}
|
|
|
|
|
|
|
|
/** Updates the streams in the fountain. */
|
|
|
|
public void update(StarFountain fountain) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** The current motion. */
|
|
|
|
private Motion motion = Motion.NONE;
|
2016-12-23 10:03:32 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes the star fountain.
|
|
|
|
* @param containerWidth the container width
|
|
|
|
* @param containerHeight the container height
|
|
|
|
*/
|
|
|
|
public StarFountain(int containerWidth, int containerHeight) {
|
|
|
|
Image img = GameImage.STAR2.getImage();
|
2016-12-23 22:53:12 +01:00
|
|
|
float xOffset = containerWidth * 0.125f;
|
|
|
|
this.xDirection = containerWidth / 2f - xOffset;
|
|
|
|
this.yDirection = -containerHeight * 0.85f;
|
|
|
|
this.left = new StarStream(xOffset - img.getWidth() / 2f, containerHeight, 0, yDirection, 0);
|
|
|
|
this.right = new StarStream(containerWidth - xOffset - img.getWidth() / 2f, containerHeight, 0, yDirection, 0);
|
|
|
|
left.setScaleSpread(1.1f, 0.2f);
|
|
|
|
right.setScaleSpread(1.1f, 0.2f);
|
2016-12-23 10:03:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the star fountain.
|
|
|
|
*/
|
|
|
|
public void draw() {
|
|
|
|
left.draw();
|
|
|
|
right.draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the stars in the fountain by a delta interval.
|
|
|
|
* @param delta the delta interval since the last call
|
|
|
|
*/
|
|
|
|
public void update(int delta) {
|
|
|
|
left.update(delta);
|
|
|
|
right.update(delta);
|
2016-12-23 22:53:12 +01:00
|
|
|
|
2016-12-23 10:03:32 +01:00
|
|
|
if (burstProgress.update(delta)) {
|
2016-12-23 22:53:12 +01:00
|
|
|
motion.update(this);
|
2016-12-23 10:03:32 +01:00
|
|
|
int size = Math.round((float) delta / burstProgress.getDuration() * BURST_SIZE);
|
|
|
|
left.burst(size);
|
|
|
|
right.burst(size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a burst of stars to be processed during the next {@link #update(int)} call.
|
|
|
|
* @param wait if {@code true}, will not burst if a previous burst is in progress
|
|
|
|
*/
|
|
|
|
public void burst(boolean wait) {
|
|
|
|
if (wait && (burstProgress.getTime() < burstProgress.getDuration() || !left.isEmpty() || !right.isEmpty()))
|
2016-12-23 22:53:12 +01:00
|
|
|
return; // previous burst in progress
|
2016-12-23 10:03:32 +01:00
|
|
|
|
|
|
|
burstProgress.setTime(0);
|
2016-12-23 22:53:12 +01:00
|
|
|
|
|
|
|
Motion lastMotion = motion;
|
|
|
|
motion = Motion.values()[(int) (Math.random() * Motion.values().length)];
|
|
|
|
if (motion == lastMotion) // don't do the same sweep twice
|
|
|
|
motion = Motion.NONE;
|
|
|
|
motion.init(this);
|
2016-12-23 10:03:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the stars currently in the fountain.
|
|
|
|
*/
|
|
|
|
public void clear() {
|
|
|
|
left.clear();
|
|
|
|
right.clear();
|
|
|
|
burstProgress.setTime(burstProgress.getDuration());
|
2016-12-23 22:53:12 +01:00
|
|
|
motion = Motion.NONE;
|
|
|
|
motion.init(this);
|
2016-12-23 10:03:32 +01:00
|
|
|
}
|
|
|
|
}
|