From 25a7a826f1dbc81afeaa52258a8caff25a834a3e Mon Sep 17 00:00:00 2001 From: Jeffrey Han Date: Thu, 19 Feb 2015 00:33:32 -0500 Subject: [PATCH] More graphical updates, some code cleanup, and minor fixes. - The MenuButton class now fully supports hover effects (scale, fade, rotate) for Animations. - Used a fixed location for the selection buttons in the song menu (previously based on the "back" button width, which varies widely in different skins). - Added hover effects for "retry" and "exit" buttons in the ranking screen. - Changed animation speed of back/skip buttons. - Fixed a bug where main menu showed the incorrect number of songs loaded during searches. - Removed unneeded draw() methods in Utils for color filters (since 69f5aa5). - Moved Utils.drawCentered(Image, ...) into the Image class. - Added overwritten Image class to Maven excludes. Signed-off-by: Jeffrey Han --- pom.xml | 1 + src/itdelatrisu/opsu/MenuButton.java | 105 ++++++++++-------- src/itdelatrisu/opsu/OsuGroupList.java | 5 + src/itdelatrisu/opsu/Utils.java | 43 +------ src/itdelatrisu/opsu/objects/Circle.java | 6 +- src/itdelatrisu/opsu/objects/Slider.java | 10 +- .../objects/curves/CircumscribedCircle.java | 4 +- .../opsu/objects/curves/LinearBezier.java | 4 +- src/itdelatrisu/opsu/states/ButtonMenu.java | 2 +- src/itdelatrisu/opsu/states/Game.java | 2 +- src/itdelatrisu/opsu/states/GameRanking.java | 11 +- src/itdelatrisu/opsu/states/MainMenu.java | 2 +- src/itdelatrisu/opsu/states/SongMenu.java | 7 +- src/org/newdawn/slick/Image.java | 13 ++- 14 files changed, 107 insertions(+), 108 deletions(-) diff --git a/pom.xml b/pom.xml index a034b880..c81883b3 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,7 @@ org.slick2d:slick2d-core + org/newdawn/slick/Image.* org/newdawn/slick/Music.* org/newdawn/slick/openal/AudioInputStream* org/newdawn/slick/openal/OpenALStreamPlayer* diff --git a/src/itdelatrisu/opsu/MenuButton.java b/src/itdelatrisu/opsu/MenuButton.java index 249dd189..8233d9d7 100644 --- a/src/itdelatrisu/opsu/MenuButton.java +++ b/src/itdelatrisu/opsu/MenuButton.java @@ -167,57 +167,67 @@ public class MenuButton { /** * Draws the button. */ - public void draw() { draw(null); } + public void draw() { draw(Color.white); } /** * Draw the button with a color filter. * @param filter the color to filter with when drawing */ + @SuppressWarnings("deprecation") public void draw(Color filter) { - if (img != null) { - if (imgL == null) { - if (hoverEffect == 0) - Utils.draw(img, x - xRadius, y - yRadius, filter); - else { - Image hoverImg = img; - float oldAlpha = img.getAlpha(); - float oldAngle = img.getRotation(); - if ((hoverEffect & EFFECT_EXPAND) > 0) { - if (scale != 1f) { - hoverImg = hoverImg.getScaledCopy(scale); - hoverImg.setAlpha(oldAlpha); - } - } - if ((hoverEffect & EFFECT_FADE) > 0) - hoverImg.setAlpha(alpha); - if ((hoverEffect & EFFECT_ROTATE) > 0) - hoverImg.setRotation(angle); - Utils.draw(hoverImg, x - xRadius, y - yRadius, filter); - if (hoverImg != img) { - hoverImg.setAlpha(oldAlpha); - hoverImg.setRotation(oldAngle); + // animations: get current frame + Image image = this.img; + if (image == null) { + anim.updateNoDraw(); + image = anim.getCurrentFrame(); + } + + // normal images + if (imgL == null) { + if (hoverEffect == 0) + image.draw(x - xRadius, y - yRadius, filter); + else { + float oldAlpha = image.getAlpha(); + float oldAngle = image.getRotation(); + if ((hoverEffect & EFFECT_EXPAND) > 0) { + if (scale != 1f) { + image = image.getScaledCopy(scale); + image.setAlpha(oldAlpha); } } - } else { - if (hoverEffect == 0) { - Utils.draw(img, x - xRadius + imgL.getWidth(), y - yRadius, filter); - Utils.draw(imgL, x - xRadius, y - yRadius, filter); - Utils.draw(imgR, x + xRadius - imgR.getWidth(), y - yRadius, filter); - } else if ((hoverEffect & EFFECT_FADE) > 0) { - float a = img.getAlpha(), aL = imgL.getAlpha(), aR = imgR.getAlpha(); - img.setAlpha(alpha); - imgL.setAlpha(alpha); - imgR.setAlpha(alpha); - Utils.draw(img, x - xRadius + imgL.getWidth(), y - yRadius, filter); - Utils.draw(imgL, x - xRadius, y - yRadius, filter); - Utils.draw(imgR, x + xRadius - imgR.getWidth(), y - yRadius, filter); - img.setAlpha(a); - imgL.setAlpha(aL); - imgR.setAlpha(aR); + if ((hoverEffect & EFFECT_FADE) > 0) + image.setAlpha(alpha); + if ((hoverEffect & EFFECT_ROTATE) > 0) + image.setRotation(angle); + image.draw(x - xRadius, y - yRadius, filter); + if (image != this.img) { + image.setAlpha(oldAlpha); + image.setRotation(oldAngle); } } - } else - Utils.draw(anim, x - xRadius, y - yRadius, filter); + } + + // 3-part images + else { + if (hoverEffect == 0) { + image.draw(x - xRadius + imgL.getWidth(), y - yRadius, filter); + imgL.draw(x - xRadius, y - yRadius, filter); + imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius, filter); + } else if ((hoverEffect & EFFECT_FADE) > 0) { + float a = image.getAlpha(), aL = imgL.getAlpha(), aR = imgR.getAlpha(); + image.setAlpha(alpha); + imgL.setAlpha(alpha); + imgR.setAlpha(alpha); + image.draw(x - xRadius + imgL.getWidth(), y - yRadius, filter); + imgL.draw(x - xRadius, y - yRadius, filter); + imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius, filter); + image.setAlpha(a); + imgL.setAlpha(aL); + imgR.setAlpha(aR); + } + } + + // text if (text != null) font.drawString(x - font.getWidth(text) / 2f, y - font.getLineHeight() / 2f, text, color); } @@ -365,14 +375,15 @@ public class MenuButton { * and expansion direction. */ private void setHoverRadius() { - if (img == null) - return; + Image image = this.img; + if (image == null) + image = anim.getCurrentFrame(); int xOffset = 0, yOffset = 0; if (dir != Expand.CENTER) { // offset by difference between normal/scaled image dimensions - xOffset = (int) ((scale - 1f) * img.getWidth()); - yOffset = (int) ((scale - 1f) * img.getHeight()); + xOffset = (int) ((scale - 1f) * image.getWidth()); + yOffset = (int) ((scale - 1f) * image.getHeight()); if (dir == Expand.UP || dir == Expand.DOWN) xOffset = 0; // no horizontal offset if (dir == Expand.RIGHT || dir == Expand.LEFT) @@ -382,7 +393,7 @@ public class MenuButton { if (dir == Expand.DOWN || dir == Expand.DOWN_LEFT || dir == Expand.DOWN_RIGHT) yOffset *= -1; // flip y for down } - this.xRadius = ((img.getWidth() * scale) + xOffset) / 2f; - this.yRadius = ((img.getHeight() * scale) + yOffset) / 2f; + this.xRadius = ((image.getWidth() * scale) + xOffset) / 2f; + this.yRadius = ((image.getHeight() * scale) + yOffset) / 2f; } } diff --git a/src/itdelatrisu/opsu/OsuGroupList.java b/src/itdelatrisu/opsu/OsuGroupList.java index d3375134..3fa4fcd8 100644 --- a/src/itdelatrisu/opsu/OsuGroupList.java +++ b/src/itdelatrisu/opsu/OsuGroupList.java @@ -239,6 +239,11 @@ public class OsuGroupList { */ public int getMapCount() { return mapCount; } + /** + * Returns the total number of parsed maps sets. + */ + public int getMapSetCount() { return parsedNodes.size(); } + /** * Returns the OsuGroupNode at an index, disregarding expansions. */ diff --git a/src/itdelatrisu/opsu/Utils.java b/src/itdelatrisu/opsu/Utils.java index ae4ee02c..6cd1e656 100644 --- a/src/itdelatrisu/opsu/Utils.java +++ b/src/itdelatrisu/opsu/Utils.java @@ -223,7 +223,7 @@ public class Utils { // back button if (GameImage.MENU_BACK.getImages() != null) { - Animation back = GameImage.MENU_BACK.getAnimation(200); + Animation back = GameImage.MENU_BACK.getAnimation(120); backButton = new MenuButton(back, back.getWidth() / 2f, height - (back.getHeight() / 2f)); } else { Image back = GameImage.MENU_BACK.getImage(); @@ -258,21 +258,10 @@ public class Utils { filter = (isHover) ? Utils.COLOR_RED_HOVER : Color.red; textColor = Color.white; } - Utils.drawCentered(tabImage, x, y, filter); + tabImage.drawCentered(x, y, filter); Utils.FONT_MEDIUM.drawString(tabTextX, tabTextY, text, textColor); } - /** - * Draws an image based on its center with a color filter. - * @param img the image to draw - * @param x the center x coordinate - * @param y the center y coordinate - * @param color the color filter to apply - */ - public static void drawCentered(Image img, float x, float y, Color color) { - img.draw(x - (img.getWidth() / 2f), y - (img.getHeight() / 2f), color); - } - /** * Draws an animation based on its center. * @param anim the animation to draw @@ -283,34 +272,6 @@ public class Utils { anim.draw(x - (anim.getWidth() / 2f), y - (anim.getHeight() / 2f)); } - /** - * Draws an image at the given location. - * @param img the image to draw - * @param x the x coordinate - * @param y the y coordinate - * @param color the color filter to apply - */ - public static void draw(Image img, float x, float y, Color color) { - if (color == null) - img.draw(x, y); - else - img.draw(x, y, color); - } - - /** - * Draws an animation at the given location. - * @param anim the animation to draw - * @param x the x coordinate - * @param y the y coordinate - * @param color the color filter to apply - */ - public static void draw(Animation anim, float x, float y, Color color) { - if (color == null) - anim.draw(x, y); - else - anim.draw(x, y, color); - } - /** * Returns a bounded value for a base value and displacement. * @param base the initial value diff --git a/src/itdelatrisu/opsu/objects/Circle.java b/src/itdelatrisu/opsu/objects/Circle.java index 1922c47a..d29470de 100644 --- a/src/itdelatrisu/opsu/objects/Circle.java +++ b/src/itdelatrisu/opsu/objects/Circle.java @@ -89,13 +89,13 @@ public class Circle implements HitObject { float approachScale = 1 + scale * 3; color.a = 1 - scale; - Utils.drawCentered(GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale), x, y, color); + GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color); float alpha = Utils.clamp((1 - scale) * 2, 0, 1); color.a = alpha; Utils.COLOR_WHITE_FADE.a = alpha; - Utils.drawCentered(GameImage.HITCIRCLE.getImage(), x, y, color); - Utils.drawCentered(GameImage.HITCIRCLE_OVERLAY.getImage(), x, y, Utils.COLOR_WHITE_FADE); + GameImage.HITCIRCLE.getImage().drawCentered(x, y, color); + GameImage.HITCIRCLE_OVERLAY.getImage().drawCentered(x, y, Utils.COLOR_WHITE_FADE); color.a = oldAlpha; Utils.COLOR_WHITE_FADE.a = 1f; diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 2903b438..0076a060 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -174,12 +174,12 @@ public class Slider implements HitObject { // end circle float[] endPos = curve.pointAt(1); - Utils.drawCentered(hitCircle, endPos[0], endPos[1], color); - Utils.drawCentered(hitCircleOverlay, endPos[0], endPos[1], Utils.COLOR_WHITE_FADE); + hitCircle.drawCentered(endPos[0], endPos[1], color); + hitCircleOverlay.drawCentered(endPos[0], endPos[1], Utils.COLOR_WHITE_FADE); // start circle - Utils.drawCentered(hitCircle, x, y, color); - Utils.drawCentered(hitCircleOverlay, x, y, Utils.COLOR_WHITE_FADE); + hitCircle.drawCentered(x, y, color); + hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE); if (sliderClicked) ; // don't draw current combo number if already clicked else @@ -213,7 +213,7 @@ public class Slider implements HitObject { if (timeDiff >= 0) { // approach circle color.a = 1 - scale; - Utils.drawCentered(GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale), x, y, color); + GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color); } else { float[] c = curve.pointAt(getT(trackPosition, false)); float[] c2 = curve.pointAt(getT(trackPosition, false) + 0.01f); diff --git a/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java b/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java index 2b4c22b3..84302c04 100644 --- a/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java +++ b/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java @@ -174,11 +174,11 @@ public class CircumscribedCircle extends Curve { Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage(); for (int i = 0; i < step; i++) { float[] xy = pointAt(i / step); - Utils.drawCentered(hitCircleOverlay, xy[0], xy[1], Utils.COLOR_WHITE_FADE); + hitCircleOverlay.drawCentered(xy[0], xy[1], Utils.COLOR_WHITE_FADE); } for (int i = 0; i < step; i++) { float[] xy = pointAt(i / step); - Utils.drawCentered(hitCircle, xy[0], xy[1], color); + hitCircle.drawCentered(xy[0], xy[1], color); } } diff --git a/src/itdelatrisu/opsu/objects/curves/LinearBezier.java b/src/itdelatrisu/opsu/objects/curves/LinearBezier.java index 249e77dd..2f1d01a1 100644 --- a/src/itdelatrisu/opsu/objects/curves/LinearBezier.java +++ b/src/itdelatrisu/opsu/objects/curves/LinearBezier.java @@ -164,9 +164,9 @@ public class LinearBezier extends Curve { Image hitCircle = GameImage.HITCIRCLE.getImage(); Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage(); for (int i = curve.length - 2; i >= 0; i--) - Utils.drawCentered(hitCircleOverlay, curve[i].x, curve[i].y, Utils.COLOR_WHITE_FADE); + hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Utils.COLOR_WHITE_FADE); for (int i = curve.length - 2; i >= 0; i--) - Utils.drawCentered(hitCircle, curve[i].x, curve[i].y, color); + hitCircle.drawCentered(curve[i].x, curve[i].y, color); } @Override diff --git a/src/itdelatrisu/opsu/states/ButtonMenu.java b/src/itdelatrisu/opsu/states/ButtonMenu.java index 76d33a53..cdc7b08e 100644 --- a/src/itdelatrisu/opsu/states/ButtonMenu.java +++ b/src/itdelatrisu/opsu/states/ButtonMenu.java @@ -485,7 +485,7 @@ public class ButtonMenu extends BasicGameState { RESET_MODS ("Reset All Mods", Color.red) { @Override public void click(GameContainer container, StateBasedGame game) { - SoundController.playSound(SoundEffect.MENUHIT); + SoundController.playSound(SoundEffect.MENUCLICK); for (GameMod mod : GameMod.values()) { if (mod.isActive()) mod.toggle(false); diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 66d0e2cc..095b734c 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -810,7 +810,7 @@ public class Game extends BasicGameState { // skip button if (GameImage.SKIP.getImages() != null) { - Animation skip = GameImage.SKIP.getAnimation(200); + Animation skip = GameImage.SKIP.getAnimation(120); skipButton = new MenuButton(skip, width - skip.getWidth() / 2f, height - (skip.getHeight() / 2f)); } else { Image skip = GameImage.SKIP.getImage(); diff --git a/src/itdelatrisu/opsu/states/GameRanking.java b/src/itdelatrisu/opsu/states/GameRanking.java index 4a228070..4bec2b88 100644 --- a/src/itdelatrisu/opsu/states/GameRanking.java +++ b/src/itdelatrisu/opsu/states/GameRanking.java @@ -84,6 +84,8 @@ public class GameRanking extends BasicGameState { width - (exit.getWidth() / 2f), (height * 0.97f) - (exit.getHeight() / 2f) ); + retryButton.setHoverFade(0.6f); + exitButton.setHoverFade(0.6f); } @Override @@ -119,6 +121,10 @@ public class GameRanking extends BasicGameState { Utils.updateCursor(delta); Utils.updateVolumeDisplay(delta); int mouseX = input.getMouseX(), mouseY = input.getMouseY(); + if (data.isGameplay()) { + retryButton.hoverUpdate(delta, mouseX, mouseY); + exitButton.hoverUpdate(delta, mouseX, mouseY); + } Utils.getBackButton().hoverUpdate(delta, mouseX, mouseY); } @@ -174,8 +180,11 @@ public class GameRanking extends BasicGameState { if (!data.isGameplay()) { if (!MusicController.isTrackDimmed()) MusicController.toggleTrackDimmed(0.5f); - } else + } else { SoundController.playSound(SoundEffect.APPLAUSE); + retryButton.resetHover(); + exitButton.resetHover(); + } } @Override diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index 2ff569fd..72b8a569 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -236,7 +236,7 @@ public class MainMenu extends BasicGameState { g.setFont(Utils.FONT_MEDIUM); int lineHeight = Utils.FONT_MEDIUM.getLineHeight() * 9 / 10; g.drawString(String.format("Loaded %d songs and %d beatmaps.", - OsuGroupList.get().size(), OsuGroupList.get().getMapCount()), marginX, marginY); + OsuGroupList.get().getMapSetCount(), OsuGroupList.get().getMapCount()), marginX, marginY); if (MusicController.isTrackLoading()) g.drawString("Track loading...", marginX, marginY + lineHeight); else if (MusicController.trackExists()) { diff --git a/src/itdelatrisu/opsu/states/SongMenu.java b/src/itdelatrisu/opsu/states/SongMenu.java index bc69798b..c39e7fa6 100644 --- a/src/itdelatrisu/opsu/states/SongMenu.java +++ b/src/itdelatrisu/opsu/states/SongMenu.java @@ -253,9 +253,10 @@ public class SongMenu extends BasicGameState { search.setMaxLength(60); // selection buttons - float selectX = GameImage.MENU_BACK.getAnimation(1).getWidth() * 1.75f; - float selectY = height - GameImage.SELECTION_MODS.getImage().getHeight() / 2f; - float selectOffset = GameImage.SELECTION_MODS.getImage().getWidth() * 1.05f; + Image selectionMods = GameImage.SELECTION_MODS.getImage(); + float selectX = width * 0.183f + selectionMods.getWidth() / 2f; + float selectY = height - selectionMods.getHeight() / 2f; + float selectOffset = selectionMods.getWidth() * 1.05f; selectModsButton = new MenuButton(GameImage.SELECTION_MODS_OVERLAY.getImage(), selectX, selectY); selectRandomButton = new MenuButton(GameImage.SELECTION_RANDOM_OVERLAY.getImage(), diff --git a/src/org/newdawn/slick/Image.java b/src/org/newdawn/slick/Image.java index c3a1947e..fe0fb45f 100644 --- a/src/org/newdawn/slick/Image.java +++ b/src/org/newdawn/slick/Image.java @@ -556,7 +556,7 @@ public class Image implements Renderable { } /** - * Draw the image based on it's center + * Draw the image based on its center * * @param x The x coordinate to place the image's center at * @param y The y coordinate to place the image's center at @@ -564,6 +564,17 @@ public class Image implements Renderable { public void drawCentered(float x, float y) { draw(x-(getWidth()/2),y-(getHeight()/2)); } + + /** + * Draw the image based on its center with a color filter + * + * @param x The x coordinate to place the image's center at + * @param y The y coordinate to place the image's center at + * @param color The color filter to apply + */ + public void drawCentered(float x, float y, Color color) { + draw(x - (getWidth() / 2f), y - (getHeight() / 2f), color); + } /** * Draw this image at the specified location