Star fountain motions.

Star fountains now "randomly" spray upwards, inwards, or outwards.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2016-12-23 16:53:12 -05:00
parent 5704b8aa10
commit 9f2aa7c1fb
5 changed files with 114 additions and 20 deletions

View File

@ -139,7 +139,7 @@ public class Options {
private static String themeString = "theme.mp3,Rainbows,Kevin MacLeod,219350";
/** The theme song timing point string (for computing beats to pulse the logo) . */
private static String themeTimingPoint = "-3300,545.454545454545,4,1,0,100,0,0";
private static String themeTimingPoint = "1080,545.454545454545,4,1,0,100,0,0";
/**
* Returns whether the XDG flag in the manifest (if any) is set to "true".

View File

@ -206,6 +206,8 @@ public class MusicController {
int trackPosition = Math.max(0, getPosition());
double beatLength = lastTimingPoint.getBeatLength() * 100.0;
int beatTime = lastTimingPoint.getTime();
if (trackPosition < beatTime)
trackPosition += (beatLength / 100.0) * (beatTime / lastTimingPoint.getBeatLength());
return (float) ((((trackPosition - beatTime) * 100.0) % beatLength) / beatLength);
}
@ -232,6 +234,8 @@ public class MusicController {
int trackPosition = Math.max(0, getPosition());
double measureLength = lastTimingPoint.getBeatLength() * lastTimingPoint.getMeter() * k * 100.0;
int beatTime = lastTimingPoint.getTime();
if (trackPosition < beatTime)
trackPosition += (measureLength / 100.0) * (beatTime / lastTimingPoint.getBeatLength());
return (float) ((((trackPosition - beatTime) * 100.0) % measureLength) / measureLength);
}

View File

@ -498,6 +498,7 @@ public class MainMenu extends BasicGameState {
// music position bar
if (MusicController.isPlaying()) {
if (musicPositionBarContains(x, y)) {
lastMeasureProgress = 0f;
float pos = (x - musicBarX) / musicBarWidth;
MusicController.setPosition((int) (pos * MusicController.getDuration()));
return;
@ -519,6 +520,7 @@ public class MainMenu extends BasicGameState {
UI.sendBarNotification(">> Next");
return;
} else if (musicPrevious.contains(x, y)) {
lastMeasureProgress = 0f;
if (!previous.isEmpty()) {
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
menu.setFocus(BeatmapSetList.get().getBaseNode(previous.pop()), -1, true, false);
@ -685,6 +687,7 @@ public class MainMenu extends BasicGameState {
* @param user {@code true} if this was user-initiated, false otherwise (track end)
*/
private void nextTrack(boolean user) {
lastMeasureProgress = 0f;
boolean isTheme = MusicController.isThemePlaying();
if (isTheme && !user) {
// theme was playing, restart

View File

@ -11,13 +11,67 @@ import org.newdawn.slick.Image;
*/
public class StarFountain {
/** The (approximate) number of stars in each burst. */
private static final int BURST_SIZE = 80;
private static final int BURST_SIZE = 125;
/** Star streams. */
private final StarStream left, right;
/** Burst progress. */
private final AnimatedValue burstProgress = new AnimatedValue(800, 0, 1, AnimationEquation.LINEAR);
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;
/**
* Initializes the star fountain.
@ -26,19 +80,13 @@ public class StarFountain {
*/
public StarFountain(int containerWidth, int containerHeight) {
Image img = GameImage.STAR2.getImage();
float xDir = containerWidth * 0.4f, yDir = containerHeight * 0.75f;
this.left = new StarStream(-img.getWidth(), containerHeight, xDir, -yDir, 0);
this.right = new StarStream(containerWidth, containerHeight, -xDir, -yDir, 0);
setStreamProperties(left);
setStreamProperties(right);
}
/**
* Sets attributes for the given star stream.
*/
private void setStreamProperties(StarStream stream) {
stream.setDirectionSpread(60f);
stream.setDurationSpread(1100, 200);
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);
}
/**
@ -56,7 +104,9 @@ public class StarFountain {
public void update(int delta) {
left.update(delta);
right.update(delta);
if (burstProgress.update(delta)) {
motion.update(this);
int size = Math.round((float) delta / burstProgress.getDuration() * BURST_SIZE);
left.burst(size);
right.burst(size);
@ -69,9 +119,15 @@ public class StarFountain {
*/
public void burst(boolean wait) {
if (wait && (burstProgress.getTime() < burstProgress.getDuration() || !left.isEmpty() || !right.isEmpty()))
return;
return; // previous burst in progress
burstProgress.setTime(0);
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);
}
/**
@ -81,5 +137,7 @@ public class StarFountain {
left.clear();
right.clear();
burstProgress.setTime(burstProgress.getDuration());
motion = Motion.NONE;
motion.init(this);
}
}

View File

@ -56,6 +56,12 @@ public class StarStream {
/** The spread of the stars' duration, in ms. */
private int durationSpread = 300;
/** The base (mean) scale at which stars are drawn. */
private float scaleBase = 1f;
/** The spread of the stars' scale.*/
private float scaleSpread = 0f;
/** The star image. */
private final Image starImg;
@ -76,6 +82,9 @@ public class StarStream {
/** The star image rotation angle. */
private final int angle;
/** The star image scale. */
private final float scale;
/** The star animation progress. */
private final AnimatedValue animatedValue;
@ -84,13 +93,15 @@ public class StarStream {
* @param offset the position offset vector
* @param direction the direction vector
* @param angle the image rotation angle
* @param scale the image scale
* @param duration the time, in milliseconds, to show the star
* @param eqn the animation equation to use
*/
public Star(Vec2f offset, Vec2f direction, int angle, int duration, AnimationEquation eqn) {
public Star(Vec2f offset, Vec2f direction, int angle, float scale, int duration, AnimationEquation eqn) {
this.offset = offset;
this.dir = direction;
this.angle = angle;
this.scale = scale;
this.animatedValue = new AnimatedValue(duration, 0f, 1f, eqn);
}
@ -102,7 +113,7 @@ public class StarStream {
starImg.setImageColor(1f, 1f, 1f, Math.min((1 - t) * 5f, 1f));
starImg.drawEmbedded(
offset.x + t * dir.x, offset.y + t * dir.y,
starImg.getWidth(), starImg.getHeight(), angle
starImg.getWidth() * scale, starImg.getHeight() * scale, angle
);
}
@ -137,6 +148,13 @@ public class StarStream {
*/
public void setPositionSpread(float spread) { this.positionSpread = spread; }
/**
* Sets the direction of this star stream.
* @param dirX the new x-axis direction
* @param dirY the new y-axis direction
*/
public void setDirection(float dirX, float dirY) { direction.set(dirX, dirY); }
/**
* Set the direction spread of this star stream.
* @param spread the spread of the stars' direction
@ -153,6 +171,16 @@ public class StarStream {
this.durationSpread = spread;
}
/**
* Sets the scale base and spread of this star stream.
* @param base the base (mean) scale at which stars are drawn
* @param spread the spread of the stars' scale
*/
public void setScaleSpread(float base, float spread) {
this.scaleBase = base;
this.scaleSpread = spread;
}
/**
* Draws the star stream.
*/
@ -196,10 +224,11 @@ public class StarStream {
Vec2f offset = position.cpy().add(direction.cpy().nor().normalize().scale((float) getGaussian(0, positionSpread)));
Vec2f dir = direction.cpy().scale(distanceRatio).add((float) getGaussian(0, directionSpread), (float) getGaussian(0, directionSpread));
int angle = (int) getGaussian(0, 22.5);
float scale = (float) getGaussian(scaleBase, scaleSpread);
int duration = Math.max(0, (int) (distanceRatio * getGaussian(durationBase, durationSpread)));
AnimationEquation eqn = random.nextBoolean() ? AnimationEquation.IN_OUT_QUAD : AnimationEquation.OUT_QUAD;
return new Star(offset, dir, angle, duration, eqn);
return new Star(offset, dir, angle, scale, duration, eqn);
}
/**