From 9f2aa7c1fb487950afcf5204b5aa560822261193 Mon Sep 17 00:00:00 2001 From: Jeffrey Han Date: Fri, 23 Dec 2016 16:53:12 -0500 Subject: [PATCH] Star fountain motions. Star fountains now "randomly" spray upwards, inwards, or outwards. Signed-off-by: Jeffrey Han --- src/itdelatrisu/opsu/Options.java | 2 +- .../opsu/audio/MusicController.java | 4 + src/itdelatrisu/opsu/states/MainMenu.java | 3 + src/itdelatrisu/opsu/ui/StarFountain.java | 90 +++++++++++++++---- src/itdelatrisu/opsu/ui/StarStream.java | 35 +++++++- 5 files changed, 114 insertions(+), 20 deletions(-) diff --git a/src/itdelatrisu/opsu/Options.java b/src/itdelatrisu/opsu/Options.java index 03cb3824..ef7300df 100644 --- a/src/itdelatrisu/opsu/Options.java +++ b/src/itdelatrisu/opsu/Options.java @@ -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". diff --git a/src/itdelatrisu/opsu/audio/MusicController.java b/src/itdelatrisu/opsu/audio/MusicController.java index f32043e9..637c7910 100644 --- a/src/itdelatrisu/opsu/audio/MusicController.java +++ b/src/itdelatrisu/opsu/audio/MusicController.java @@ -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); } diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index 570a69f2..b3ef3974 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -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 diff --git a/src/itdelatrisu/opsu/ui/StarFountain.java b/src/itdelatrisu/opsu/ui/StarFountain.java index 6a126c33..3686bf6e 100644 --- a/src/itdelatrisu/opsu/ui/StarFountain.java +++ b/src/itdelatrisu/opsu/ui/StarFountain.java @@ -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); } } diff --git a/src/itdelatrisu/opsu/ui/StarStream.java b/src/itdelatrisu/opsu/ui/StarStream.java index 7a5701a9..0bd11480 100644 --- a/src/itdelatrisu/opsu/ui/StarStream.java +++ b/src/itdelatrisu/opsu/ui/StarStream.java @@ -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); } /**