diff --git a/res/logo2pulse.png b/res/logo2pulse.png new file mode 100644 index 00000000..56715f29 Binary files /dev/null and b/res/logo2pulse.png differ diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index 2209ef57..8f474d54 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -308,6 +308,12 @@ public enum GameImage { return img.getScaledCopy(0.75f); } }, + MENU_LOGO_PULSE ("logo2pulse", "png", false, true) { + @Override + protected Image process_sub(Image img, int w, int h) { + return img.getScaledCopy(0.75f); + } + }, MENU_PLAY ("menu-play2", "png", false, false) { @Override protected Image process_sub(Image img, int w, int h) { diff --git a/src/itdelatrisu/opsu/audio/MusicController.java b/src/itdelatrisu/opsu/audio/MusicController.java index a37e1f44..4ebb7781 100644 --- a/src/itdelatrisu/opsu/audio/MusicController.java +++ b/src/itdelatrisu/opsu/audio/MusicController.java @@ -217,6 +217,17 @@ public class MusicController { return (float) ((((trackPosition - beatTime) * 100.0) % beatLength) / beatLength); } + /** + * gets the current beat length + * @return + */ + public static Float getBeatLength() { + if (!updateTimingPoint()) + return null; + + return lastTimingPoint.getBeatLength(); + } + /** * Gets the progress of the current measure. * @return a measure progress value [0,1) where 0 marks the start of the measure and diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index f09b637d..962b632e 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -37,6 +37,8 @@ import java.awt.Desktop; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; import java.util.Stack; import org.lwjgl.opengl.Display; @@ -124,6 +126,9 @@ public class MainMenu extends BaseOpsuState { /** The star fountain. */ private StarFountain starFountain; + + private LinkedList pulseData = new LinkedList<>(); + private float lastPulseProgress; @Override protected void revalidate() { @@ -262,11 +267,25 @@ public class MainMenu extends BaseOpsuState { // draw logo (pulsing) Color color = OPTION_COLOR_MAIN_MENU_LOGO.state ? Cursor.lastCursorColor : Color.white; + for (PulseData pd : this.pulseData) { + final float progress = OUT_CUBIC.calc(pd.position / 1000f); + final float scale = pd.initialScale + (0.432f * progress); + final Image p = GameImage.MENU_LOGO_PULSE.getImage().getScaledCopy(scale); + p.setAlpha(0.15f * (1f - IN_QUAD.calc(progress))); + p.drawCentered(logo.getX(), logo.getY(), color); + } Float position = MusicController.getBeatProgress(); + Float beatLength = MusicController.getBeatLength(); boolean renderPiece = position != null; if (position == null) { position = System.currentTimeMillis() % 1000 / 1000f; + beatLength = 1000f; } + final float hoverScale = logo.getCurrentHoverExpandValue(); + if (position < this.lastPulseProgress) { + this.pulseData.add(new PulseData((int) (position*beatLength), hoverScale)); + } + this.lastPulseProgress = position; final float smoothExpandProgress; if (position < 0.05f) { smoothExpandProgress = 1f - IN_CUBIC.calc(position / 0.05f); @@ -274,7 +293,6 @@ public class MainMenu extends BaseOpsuState { smoothExpandProgress = (position - 0.05f) / 0.95f; } logo.draw(color, 0.9726f + smoothExpandProgress * 0.0274f); - final float hoverScale = logo.getCurrentHoverExpandValue(); if (renderPiece) { Image piece = GameImage.MENU_LOGO_PIECE.getImage(); piece = piece.getScaledCopy(hoverScale); @@ -364,6 +382,15 @@ public class MainMenu extends BaseOpsuState { @Override public void preRenderUpdate() { int delta = displayContainer.renderDelta; + + final Iterator pulseDataIter = this.pulseData.iterator(); + while (pulseDataIter.hasNext()) { + final PulseData pd = pulseDataIter.next(); + pd.position += delta; + if (pd.position > 1000) { + pulseDataIter.remove(); + } + } UI.update(delta); if (MusicController.trackEnded()) @@ -748,4 +775,14 @@ public class MainMenu extends BaseOpsuState { } displayContainer.switchState(state); } + + private static class PulseData { + private int position; + private float initialScale; + + private PulseData(int position, float initialScale) { + this.position = position; + this.initialScale = initialScale; + } + } }