From 020dfbde324f7c9ee928974d3f5caf5bea841a18 Mon Sep 17 00:00:00 2001 From: Jeffrey Han Date: Fri, 20 Feb 2015 16:56:41 -0500 Subject: [PATCH] Spinner updates and animated score percentage display. - Added spinner RPM display. (image by @kouyang) - Added "osu!" image for completed spinners. - Changed spinner hit result ratios to be slightly harder. Signed-off-by: Jeffrey Han --- res/spinner-rpm.png | Bin 0 -> 6819 bytes src/itdelatrisu/opsu/GameData.java | 68 ++++++++++++++++------ src/itdelatrisu/opsu/GameImage.java | 6 ++ src/itdelatrisu/opsu/objects/Circle.java | 8 +-- src/itdelatrisu/opsu/objects/Slider.java | 4 +- src/itdelatrisu/opsu/objects/Spinner.java | 21 ++++--- 6 files changed, 73 insertions(+), 34 deletions(-) create mode 100644 res/spinner-rpm.png diff --git a/res/spinner-rpm.png b/res/spinner-rpm.png new file mode 100644 index 0000000000000000000000000000000000000000..f44ed0f83fd727ee5968c05a1e0fb3b218060d12 GIT binary patch literal 6819 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 K;Z-U&(fjU literal 0 HcmV?d00001 diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index cf1f6e20..93ee852e 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -39,6 +39,9 @@ public class GameData { /** Delta multiplier for steady HP drain. */ public static final float HP_DRAIN_MULTIPLIER = 1 / 200f; + /** Time, in milliseconds, for a hit result to fade. */ + public static final int HITRESULT_FADE_TIME = 500; + /** Time, in milliseconds, for a hit error tick to fade. */ private static final int HIT_ERROR_FADE_TIME = 5000; @@ -207,6 +210,9 @@ public class GameData { /** Combo color. */ public Color color; + /** Whether the hit object was a spinner. */ + public boolean isSpinner; + /** Alpha level (for fading out). */ public float alpha = 1f; @@ -217,13 +223,15 @@ public class GameData { * @param x the center x coordinate * @param y the center y coordinate * @param color the color of the hit object + * @param isSpinner whether the hit object was a spinner */ - public OsuHitObjectResult(int time, int result, float x, float y, Color color) { + public OsuHitObjectResult(int time, int result, float x, float y, Color color, boolean isSpinner) { this.time = time; this.result = result; this.x = x; this.y = y; this.color = color; + this.isSpinner = isSpinner; } } @@ -233,6 +241,9 @@ public class GameData { /** Displayed game score (for animation, slightly behind score). */ private long scoreDisplay; + /** Displayed game score percent (for animation, slightly behind score percent). */ + private float scorePercentDisplay; + /** Current health bar percentage. */ private float health; @@ -311,6 +322,7 @@ public class GameData { public void clear() { score = 0; scoreDisplay = 0; + scorePercentDisplay = 0f; health = 100f; healthDisplay = 100f; hitResultCount = new int[HIT_MAX]; @@ -435,7 +447,7 @@ public class GameData { * @param scale the scale to apply * @param rightAlign align right (true) or left (false) */ - private void drawSymbolString(String str, int x, int y, float scale, boolean rightAlign) { + public void drawSymbolString(String str, int x, int y, float scale, boolean rightAlign) { char[] c = str.toCharArray(); int cx = x; if (rightAlign) { @@ -466,7 +478,7 @@ public class GameData { * @param fixedsize the width to use for all symbols * @param rightAlign align right (true) or left (false) */ - private void drawFixedSizeSymbolString(String str, int x, int y, float scale, float fixedsize, boolean rightAlign) { + public void drawFixedSizeSymbolString(String str, int x, int y, float scale, float fixedsize, boolean rightAlign) { char[] c = str.toCharArray(); int cx = x; if (rightAlign) { @@ -506,11 +518,9 @@ public class GameData { // score percentage int symbolHeight = getScoreSymbolImage('0').getHeight(); - float scorePercent = getScorePercent(); drawSymbolString( - String.format((scorePercent < 10f) ? "0%.2f%%" : "%.2f%%", scorePercent), - width - marginX, symbolHeight, 0.60f, true - ); + String.format((scorePercentDisplay < 10f) ? "0%.2f%%" : "%.2f%%", scorePercentDisplay), + width - marginX, symbolHeight, 0.60f, true); // map progress circle g.setAntiAlias(true); @@ -771,20 +781,27 @@ public class GameData { * @param trackPosition the current track position */ public void drawHitResults(int trackPosition) { - final int fadeDelay = 500; - Iterator iter = hitResultList.iterator(); while (iter.hasNext()) { OsuHitObjectResult hitResult = iter.next(); - if (hitResult.time + fadeDelay > trackPosition) { + if (hitResult.time + HITRESULT_FADE_TIME > trackPosition) { + // hit result hitResults[hitResult.result].setAlpha(hitResult.alpha); - hitResult.alpha = 1 - ((float) (trackPosition - hitResult.time) / fadeDelay); hitResults[hitResult.result].drawCentered(hitResult.x, hitResult.y); + hitResults[hitResult.result].setAlpha(1f); + + // spinner + if (hitResult.isSpinner && hitResult.result != HIT_MISS) { + Image spinnerOsu = GameImage.SPINNER_OSU.getImage(); + spinnerOsu.setAlpha(hitResult.alpha); + spinnerOsu.drawCentered(width / 2, height / 4); + spinnerOsu.setAlpha(1f); + } // hit lighting - if (Options.isHitLightingEnabled() && hitResult.result != HIT_MISS && + else if (Options.isHitLightingEnabled() && hitResult.result != HIT_MISS && hitResult.result != HIT_SLIDER30 && hitResult.result != HIT_SLIDER10) { - float scale = 1f + ((trackPosition - hitResult.time) / (float) fadeDelay); + float scale = 1f + ((trackPosition - hitResult.time) / (float) HITRESULT_FADE_TIME); Image scaledLighting = GameImage.LIGHTING.getImage().getScaledCopy(scale); Image scaledLighting1 = GameImage.LIGHTING1.getImage().getScaledCopy(scale); scaledLighting.setAlpha(hitResult.alpha); @@ -795,6 +812,8 @@ public class GameData { scaledLighting1.draw(hitResult.x - (scaledLighting1.getWidth() / 2f), hitResult.y - (scaledLighting1.getHeight() / 2f), hitResult.color); } + + hitResult.alpha = 1 - ((float) (trackPosition - hitResult.time) / HITRESULT_FADE_TIME); } else iter.remove(); } @@ -901,7 +920,7 @@ public class GameData { } /** - * Updates the score, health, and combo burst displays based on a delta value. + * Updates displayed elements based on a delta value. * @param delta the delta interval since the last call */ public void updateDisplays(int delta) { @@ -912,6 +931,20 @@ public class GameData { scoreDisplay = score; } + // score percent display + float scorePercent = getScorePercent(); + if (scorePercentDisplay != scorePercent) { + if (scorePercentDisplay < scorePercent) { + scorePercentDisplay += (scorePercent - scorePercentDisplay) * delta / 50f + 0.01f; + if (scorePercentDisplay > scorePercent) + scorePercentDisplay = scorePercent; + } else { + scorePercentDisplay -= (scorePercentDisplay - scorePercent) * delta / 50f + 0.01f; + if (scorePercentDisplay < scorePercent) + scorePercentDisplay = scorePercent; + } + } + // health display if (healthDisplay != health) { float shift = delta / 15f; @@ -1027,7 +1060,7 @@ public class GameData { if (!Options.isPerfectHitBurstEnabled()) ; // hide perfect hit results else - hitResultList.add(new OsuHitObjectResult(time, result, x, y, null)); + hitResultList.add(new OsuHitObjectResult(time, result, x, y, null, false)); } } @@ -1040,9 +1073,10 @@ public class GameData { * @param color the combo color * @param end true if this is the last hit object in the combo * @param hitSound the object's hit sound + * @param isSpinner whether the hit object was a spinner */ public void hitResult(int time, int result, float x, float y, Color color, - boolean end, byte hitSound) { + boolean end, byte hitSound, boolean isSpinner) { int hitValue = 0; boolean perfectHit = false; switch (result) { @@ -1109,7 +1143,7 @@ public class GameData { if (perfectHit && !Options.isPerfectHitBurstEnabled()) ; // hide perfect hit results else - hitResultList.add(new OsuHitObjectResult(time, result, x, y, color)); + hitResultList.add(new OsuHitObjectResult(time, result, x, y, color, isSpinner)); } /** diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index b000861b..335ce97a 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -134,6 +134,12 @@ public enum GameImage { SPINNER_SPIN ("spinner-spin", "png"), SPINNER_CLEAR ("spinner-clear", "png"), SPINNER_OSU ("spinner-osu", "png"), + SPINNER_RPM ("spinner-rpm", "png", false, true) { + @Override + protected Image process_sub(Image img, int w, int h) { + return img.getScaledCopy((SCORE_0.getImage().getHeight() * 1.05f) / img.getHeight()); + } + }, // Game Data COMBO_BURST ("comboburst", "comboburst-%d", "png"), diff --git a/src/itdelatrisu/opsu/objects/Circle.java b/src/itdelatrisu/opsu/objects/Circle.java index d29470de..18c73c31 100644 --- a/src/itdelatrisu/opsu/objects/Circle.java +++ b/src/itdelatrisu/opsu/objects/Circle.java @@ -141,7 +141,7 @@ public class Circle implements HitObject { data.hitResult( hitObject.getTime(), result, hitObject.getX(), hitObject.getY(), - color, comboEnd, hitObject.getHitSoundType() + color, comboEnd, hitObject.getHitSoundType(), false ); return true; } @@ -161,17 +161,17 @@ public class Circle implements HitObject { if (overlap || trackPosition > time + hitResultOffset[GameData.HIT_50]) { if (isAutoMod) // "auto" mod: catch any missed notes due to lag - data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound); + data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound, false); else // no more points can be scored, so send a miss - data.hitResult(time, GameData.HIT_MISS, x, y, null, comboEnd, hitSound); + data.hitResult(time, GameData.HIT_MISS, x, y, null, comboEnd, hitSound, false); return true; } // "auto" mod: send a perfect hit result else if (isAutoMod) { if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) { - data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound); + data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitSound, false); return true; } } diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 0076a060..4129b5ca 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -255,10 +255,10 @@ public class Slider implements HitObject { if (currentRepeats % 2 == 0) { // last circle float[] lastPos = curve.pointAt(1); data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result, - lastPos[0],lastPos[1], color, comboEnd, hitObject.getHitSoundType()); + lastPos[0],lastPos[1], color, comboEnd, hitObject.getHitSoundType(), false); } else { // first circle data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result, - hitObject.getX(), hitObject.getY(), color, comboEnd, hitObject.getHitSoundType()); + hitObject.getX(), hitObject.getY(), color, comboEnd, hitObject.getHitSoundType(), false); } return result; diff --git a/src/itdelatrisu/opsu/objects/Spinner.java b/src/itdelatrisu/opsu/objects/Spinner.java index 27a5116d..7a16f5bc 100644 --- a/src/itdelatrisu/opsu/objects/Spinner.java +++ b/src/itdelatrisu/opsu/objects/Spinner.java @@ -106,9 +106,6 @@ public class Spinner implements HitObject { int timeDiff = hitObject.getTime() - trackPosition; boolean spinnerComplete = (rotations >= rotationsNeeded); - // TODO: draw "OSU!" image after spinner ends - //GameImage.SPINNER_OSU.getImage().drawCentered(width / 2, height / 4); - // darken screen g.setColor(Utils.COLOR_BLACK_ALPHA); g.fillRect(0, 0, width, height); @@ -116,6 +113,13 @@ public class Spinner implements HitObject { if (timeDiff > 0) return; + // rpm (TODO: make this work for Auto/Spun-Out mods) + int rpm = Math.abs(Math.round(sumVelocity / storedVelocities.length * 60)); + Image rpmImg = GameImage.SPINNER_RPM.getImage(); + rpmImg.drawCentered(width / 2f, height - rpmImg.getHeight() / 2f); + data.drawSymbolString(Integer.toString(rpm), (int) ((width + rpmImg.getWidth() * 0.95f) / 2f), + (int) (height - data.getScoreSymbolImage('0').getHeight() * 1.025f), 1f, true); + // spinner meter (subimage) Image spinnerMetre = GameImage.SPINNER_METRE.getImage(); int spinnerMetreY = (spinnerComplete) ? 0 : (int) (spinnerMetre.getHeight() * (1 - (rotations / rotationsNeeded))); @@ -138,10 +142,6 @@ public class Spinner implements HitObject { if (extraRotations > 0) data.drawSymbolNumber(extraRotations * 1000, width / 2, height * 2 / 3, 1.0f); } - - // TODO: add rpm meter at bottom of spinner - // TODO 2: make this work for Auto/Spun-Out mods -// int rpm = Math.abs(Math.round(sumVelocity / storedVelocities.length * 60)); } /** @@ -150,22 +150,21 @@ public class Spinner implements HitObject { */ private int hitResult() { // TODO: verify ratios - int result; float ratio = rotations / rotationsNeeded; if (ratio >= 1.0f || GameMod.AUTO.isActive() || GameMod.SPUN_OUT.isActive()) { result = GameData.HIT_300; SoundController.playSound(SoundEffect.SPINNEROSU); - } else if (ratio >= 0.8f) + } else if (ratio >= 0.9f) result = GameData.HIT_100; - else if (ratio >= 0.5f) + else if (ratio >= 0.75f) result = GameData.HIT_50; else result = GameData.HIT_MISS; data.hitResult(hitObject.getEndTime(), result, width / 2, height / 2, - Color.transparent, true, (byte) -1); + Color.transparent, true, (byte) -1, true); return result; }