Added easing functions for all-around better animations.

These are Robert Penner's easing functions (http://robertpenner.com/easing/), refactored by CharlotteGore to only take a t parameter (https://github.com/CharlotteGore/functional-easing). Licensed under BSD (the former) and MIT (the latter).

Related changes:
- Added "AnimatedValue" utility class for updating values used in animations.
- MenuButton now uses AnimatedValue to handle its animations (still linear by default).
- Added in-out-back easings on logo, mods, and various other elements; added out-bounce easings on button menu.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han
2015-08-05 22:28:14 -05:00
parent 6a4c6a8d37
commit c91146b024
10 changed files with 588 additions and 78 deletions

View File

@@ -31,6 +31,8 @@ import itdelatrisu.opsu.beatmap.BeatmapSetList;
import itdelatrisu.opsu.beatmap.BeatmapSetNode;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
import itdelatrisu.opsu.ui.animations.AnimatedValue;
import itdelatrisu.opsu.ui.animations.AnimationEquation;
import java.util.ArrayList;
import java.util.List;
@@ -261,8 +263,11 @@ public class ButtonMenu extends BasicGameState {
/** The actual title string list, generated upon entering the state. */
private List<String> actualTitle;
/** The horizontal center offset, used for the initial button animation. */
private AnimatedValue centerOffset;
/** Initial x coordinate offsets left/right of center (for shifting animation), times width. (TODO) */
private static final float OFFSET_WIDTH_RATIO = 1 / 18f;
private static final float OFFSET_WIDTH_RATIO = 1 / 25f;
/**
* Constructor.
@@ -336,18 +341,14 @@ public class ButtonMenu extends BasicGameState {
*/
public void update(GameContainer container, int delta, int mouseX, int mouseY) {
float center = container.getWidth() / 2f;
boolean centerOffsetUpdated = centerOffset.update(delta);
float centerOffsetX = centerOffset.getValue();
for (int i = 0; i < buttons.length; i++) {
menuButtons[i].hoverUpdate(delta, mouseX, mouseY);
// move button to center
float x = menuButtons[i].getX();
if (i % 2 == 0) {
if (x < center)
menuButtons[i].setX(Math.min(x + (delta / 5f), center));
} else {
if (x > center)
menuButtons[i].setX(Math.max(x - (delta / 5f), center));
}
if (centerOffsetUpdated)
menuButtons[i].setX((i % 2 == 0) ? center + centerOffsetX : center - centerOffsetX);
}
}
@@ -404,9 +405,10 @@ public class ButtonMenu extends BasicGameState {
*/
public void enter(GameContainer container, StateBasedGame game) {
float center = container.getWidth() / 2f;
float centerOffset = container.getWidth() * OFFSET_WIDTH_RATIO;
float centerOffsetX = container.getWidth() * OFFSET_WIDTH_RATIO;
centerOffset = new AnimatedValue(700, centerOffsetX, 0, AnimationEquation.OUT_BOUNCE);
for (int i = 0; i < buttons.length; i++) {
menuButtons[i].setX(center + ((i % 2 == 0) ? centerOffset * -1 : centerOffset));
menuButtons[i].setX(center + ((i % 2 == 0) ? centerOffsetX : centerOffsetX * -1));
menuButtons[i].resetHover();
}

View File

@@ -48,6 +48,7 @@ import itdelatrisu.opsu.replay.Replay;
import itdelatrisu.opsu.replay.ReplayFrame;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
import itdelatrisu.opsu.ui.animations.AnimationEquation;
import java.io.File;
import java.util.LinkedList;
@@ -1425,6 +1426,8 @@ public class Game extends BasicGameState {
Image skip = GameImage.SKIP.getImage();
skipButton = new MenuButton(skip, width - skip.getWidth() / 2f, height - (skip.getHeight() / 2f));
}
skipButton.setHoverAnimationDuration(350);
skipButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK);
skipButton.setHoverExpand(1.1f, MenuButton.Expand.UP_LEFT);
// load other images...

View File

@@ -27,6 +27,7 @@ import itdelatrisu.opsu.audio.SoundController;
import itdelatrisu.opsu.audio.SoundEffect;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
import itdelatrisu.opsu.ui.animations.AnimationEquation;
import org.lwjgl.input.Keyboard;
import org.newdawn.slick.Color;
@@ -227,6 +228,14 @@ public class GamePauseMenu extends BasicGameState {
continueButton = new MenuButton(GameImage.PAUSE_CONTINUE.getImage(), width / 2f, height * 0.25f);
retryButton = new MenuButton(GameImage.PAUSE_RETRY.getImage(), width / 2f, height * 0.5f);
backButton = new MenuButton(GameImage.PAUSE_BACK.getImage(), width / 2f, height * 0.75f);
final int buttonAnimationDuration = 300;
continueButton.setHoverAnimationDuration(buttonAnimationDuration);
retryButton.setHoverAnimationDuration(buttonAnimationDuration);
backButton.setHoverAnimationDuration(buttonAnimationDuration);
final AnimationEquation buttonAnimationEquation = AnimationEquation.IN_OUT_BACK;
continueButton.setHoverAnimationEquation(buttonAnimationEquation);
retryButton.setHoverAnimationEquation(buttonAnimationEquation);
backButton.setHoverAnimationEquation(buttonAnimationEquation);
continueButton.setHoverExpand();
retryButton.setHoverExpand();
backButton.setHoverExpand();

View File

@@ -33,6 +33,7 @@ import itdelatrisu.opsu.downloads.Updater;
import itdelatrisu.opsu.states.ButtonMenu.MenuState;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.MenuButton.Expand;
import itdelatrisu.opsu.ui.animations.AnimationEquation;
import itdelatrisu.opsu.ui.UI;
import java.awt.Desktop;
@@ -145,9 +146,18 @@ public class MainMenu extends BasicGameState {
exitButton = new MenuButton(exitImg,
width * 0.75f - exitOffset, (height / 2) + (exitImg.getHeight() / 2f)
);
logo.setHoverExpand(1.05f);
playButton.setHoverExpand(1.05f);
exitButton.setHoverExpand(1.05f);
final int logoAnimationDuration = 350;
logo.setHoverAnimationDuration(logoAnimationDuration);
playButton.setHoverAnimationDuration(logoAnimationDuration);
exitButton.setHoverAnimationDuration(logoAnimationDuration);
final AnimationEquation logoAnimationEquation = AnimationEquation.IN_OUT_BACK;
logo.setHoverAnimationEquation(logoAnimationEquation);
playButton.setHoverAnimationEquation(logoAnimationEquation);
exitButton.setHoverAnimationEquation(logoAnimationEquation);
final float logoHoverScale = 1.1f;
logo.setHoverExpand(logoHoverScale);
playButton.setHoverExpand(logoHoverScale);
exitButton.setHoverExpand(logoHoverScale);
// initialize music buttons
int musicWidth = GameImage.MUSIC_PLAY.getImage().getWidth();
@@ -170,6 +180,8 @@ public class MainMenu extends BasicGameState {
// initialize downloads button
Image dlImg = GameImage.DOWNLOADS.getImage();
downloadsButton = new MenuButton(dlImg, width - dlImg.getWidth() / 2f, height / 2f);
downloadsButton.setHoverAnimationDuration(350);
downloadsButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK);
downloadsButton.setHoverExpand(1.03f, Expand.LEFT);
// initialize repository button
@@ -179,6 +191,8 @@ public class MainMenu extends BasicGameState {
repoButton = new MenuButton(repoImg,
startX - repoImg.getWidth(), startY - repoImg.getHeight()
);
repoButton.setHoverAnimationDuration(350);
repoButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK);
repoButton.setHoverExpand();
startX -= repoImg.getWidth() * 1.75f;
} else