diff --git a/src/itdelatrisu/opsu/objects/Circle.java b/src/itdelatrisu/opsu/objects/Circle.java index 7818ba58..f67be5ec 100644 --- a/src/itdelatrisu/opsu/objects/Circle.java +++ b/src/itdelatrisu/opsu/objects/Circle.java @@ -36,9 +36,6 @@ import org.newdawn.slick.Graphics; * Data type representing a circle object. */ public class Circle implements GameObject { - /** The amount of time, in milliseconds, to fade in the circle. */ - private static final int FADE_IN_TIME = 375; - /** The diameter of hit circles. */ private static float diameter; @@ -94,15 +91,20 @@ public class Circle implements GameObject { @Override public void draw(Graphics g, int trackPosition) { int timeDiff = hitObject.getTime() - trackPosition; - float scale = timeDiff / (float) game.getApproachTime(); - float fadeinScale = (timeDiff - game.getApproachTime() + FADE_IN_TIME) / (float) FADE_IN_TIME; + final int approachTime = game.getApproachTime(); + final int fadeInTime = game.getFadeInTime(); + float scale = timeDiff / (float) approachTime; float approachScale = 1 + scale * 3; + float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime; float alpha = Utils.clamp(1 - fadeinScale, 0, 1); if (GameMod.HIDDEN.isActive()) { - float fadeOutScale = -(float)(timeDiff-game.getApproachTime())/game.getDecayTime(); - float fadeOutAlpha = Utils.clamp(1-fadeOutScale, 0, 1); - alpha = Math.min(alpha, fadeOutAlpha); + final int hiddenDecayTime = game.getHiddenDecayTime(); + final int hiddenTimeDiff = game.getHiddenTimeDiff(); + if (fadeinScale <= 0f && timeDiff < hiddenTimeDiff + hiddenDecayTime) { + float hiddenAlpha = (timeDiff < hiddenTimeDiff) ? 0f : (timeDiff - hiddenTimeDiff) / (float) hiddenDecayTime; + alpha = Math.min(alpha, hiddenAlpha); + } } float oldAlpha = Colors.WHITE_FADE.a; diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 160f74aa..82f48355 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -57,9 +57,6 @@ public class Slider implements GameObject { /** The diameter of hit circles. */ private static float diameter; - /** The amount of time, in milliseconds, to fade in the slider. */ - private static final int FADE_IN_TIME = 375; - /** The associated HitObject. */ private HitObject hitObject; @@ -179,9 +176,11 @@ public class Slider implements GameObject { @Override public void draw(Graphics g, int trackPosition) { int timeDiff = hitObject.getTime() - trackPosition; - float scale = timeDiff / (float) game.getApproachTime(); - float fadeinScale = (timeDiff - game.getApproachTime() + FADE_IN_TIME) / (float) FADE_IN_TIME; + final int approachTime = game.getApproachTime(); + final int fadeInTime = game.getFadeInTime(); + float scale = timeDiff / (float) approachTime; float approachScale = 1 + scale * 3; + float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime; float alpha = Utils.clamp(1 - fadeinScale, 0, 1); boolean overlayAboveNumber = Options.getSkin().isHitCircleOverlayAboveNumber(); @@ -212,9 +211,12 @@ public class Slider implements GameObject { } } if (GameMod.HIDDEN.isActive()) { - float fadeOutScale = -(float) (timeDiff - game.getApproachTime()) / game.getDecayTime(); - float fadeOutAlpha = Utils.clamp(1 - fadeOutScale, 0, 1); - alpha = Math.min(alpha, fadeOutAlpha); + final int hiddenDecayTime = game.getHiddenDecayTime(); + final int hiddenTimeDiff = game.getHiddenTimeDiff(); + if (fadeinScale <= 0f && timeDiff < hiddenTimeDiff + hiddenDecayTime) { + float hiddenAlpha = (timeDiff < hiddenTimeDiff) ? 0f : (timeDiff - hiddenTimeDiff) / (float) hiddenDecayTime; + alpha = Math.min(alpha, hiddenAlpha); + } } if (sliderClickedInitial) ; // don't draw current combo number if already clicked diff --git a/src/itdelatrisu/opsu/objects/Spinner.java b/src/itdelatrisu/opsu/objects/Spinner.java index 53d67639..1ac9d7cd 100644 --- a/src/itdelatrisu/opsu/objects/Spinner.java +++ b/src/itdelatrisu/opsu/objects/Spinner.java @@ -51,9 +51,6 @@ public class Spinner implements GameObject { /** The amount of time, in milliseconds, before another velocity is stored. */ private static final float DELTA_UPDATE_TIME = 1000 / 60f; - /** The amount of time, in milliseconds, to fade in the spinner. */ - private static final int FADE_IN_TIME = 500; - /** Angle mod multipliers: "auto" (477rpm), "spun out" (287rpm) */ private static final float AUTO_MULTIPLIER = 1 / 20f, // angle = 477/60f * delta/1000f * TWO_PI; @@ -70,6 +67,9 @@ public class Spinner implements GameObject { /** The associated HitObject. */ private HitObject hitObject; + /** The associated Game object. */ + private Game game; + /** The associated GameData object. */ private GameData data; @@ -125,6 +125,7 @@ public class Spinner implements GameObject { */ public Spinner(HitObject hitObject, Game game, GameData data) { this.hitObject = hitObject; + this.game = game; this.data = data; /* @@ -176,11 +177,12 @@ public class Spinner implements GameObject { public void draw(Graphics g, int trackPosition) { // only draw spinners shortly before start time int timeDiff = hitObject.getTime() - trackPosition; - if (timeDiff - FADE_IN_TIME > 0) + final int fadeInTime = game.getFadeInTime(); + if (timeDiff - fadeInTime > 0) return; boolean spinnerComplete = (rotations >= rotationsNeeded); - float alpha = Utils.clamp(1 - (float) timeDiff / FADE_IN_TIME, 0f, 1f); + float alpha = Utils.clamp(1 - (float) timeDiff / fadeInTime, 0f, 1f); // darken screen if (Options.getSkin().isSpinnerFadePlayfield()) { diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index c22bab62..ac13f881 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -18,6 +18,25 @@ package itdelatrisu.opsu.states; +import java.io.File; +import java.util.LinkedList; +import java.util.Stack; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.Display; +import org.newdawn.slick.Animation; +import org.newdawn.slick.Color; +import org.newdawn.slick.GameContainer; +import org.newdawn.slick.Graphics; +import org.newdawn.slick.Image; +import org.newdawn.slick.Input; +import org.newdawn.slick.SlickException; +import org.newdawn.slick.state.BasicGameState; +import org.newdawn.slick.state.StateBasedGame; +import org.newdawn.slick.state.transition.EmptyTransition; +import org.newdawn.slick.state.transition.FadeInTransition; +import org.newdawn.slick.state.transition.FadeOutTransition; + import itdelatrisu.opsu.ErrorHandler; import itdelatrisu.opsu.GameData; import itdelatrisu.opsu.GameImage; @@ -52,25 +71,6 @@ import itdelatrisu.opsu.ui.MenuButton; import itdelatrisu.opsu.ui.UI; import itdelatrisu.opsu.ui.animations.AnimationEquation; -import java.io.File; -import java.util.LinkedList; -import java.util.Stack; - -import org.lwjgl.input.Keyboard; -import org.lwjgl.opengl.Display; -import org.newdawn.slick.Animation; -import org.newdawn.slick.Color; -import org.newdawn.slick.GameContainer; -import org.newdawn.slick.Graphics; -import org.newdawn.slick.Image; -import org.newdawn.slick.Input; -import org.newdawn.slick.SlickException; -import org.newdawn.slick.state.BasicGameState; -import org.newdawn.slick.state.StateBasedGame; -import org.newdawn.slick.state.transition.EmptyTransition; -import org.newdawn.slick.state.transition.FadeInTransition; -import org.newdawn.slick.state.transition.FadeOutTransition; - /** * "Game" state. */ @@ -119,9 +119,14 @@ public class Game extends BasicGameState { /** Hit object approach time, in milliseconds. */ private int approachTime; - /** Decay time for elements in "Hidden" mod, in milliseconds. */ - //TODO: figure out actual formula for decay time - private int decayTime = 800; + /** The amount of time for hit objects to fade in, in milliseconds. */ + private int fadeInTime; + + /** Decay time for hit objects in the "Hidden" mod, in milliseconds. */ + private int hiddenDecayTime; + + /** Time before the hit object time by which the objects have completely faded in the "Hidden" mod, in milliseconds. */ + private int hiddenTimeDiff; /** Time offsets for obtaining each hit result (indexed by HIT_* constants). */ private int[] hitResultOffset; @@ -1480,6 +1485,12 @@ public class Game extends BasicGameState { int diameter = (int) (104 - (circleSize * 8)); HitObject.setStackOffset(diameter * STACK_OFFSET_MODIFIER); + // approachRate (hit object approach time) + if (approachRate < 5) + approachTime = (int) (1800 - (approachRate * 120)); + else + approachTime = (int) (1200 - ((approachRate - 5) * 150)); + // initialize objects Circle.init(container, circleSize); Slider.init(container, circleSize, beatmap); @@ -1487,12 +1498,6 @@ public class Game extends BasicGameState { Curve.init(container.getWidth(), container.getHeight(), circleSize, (Options.isBeatmapSkinIgnored()) ? Options.getSkin().getSliderBorderColor() : beatmap.getSliderBorderColor()); - // approachRate (hit object approach time) - if (approachRate < 5) - approachTime = (int) (1800 - (approachRate * 120)); - else - approachTime = (int) (1200 - ((approachRate - 5) * 150)); - // overallDifficulty (hit result time offsets) hitResultOffset = new int[GameData.HIT_MAX]; hitResultOffset[GameData.HIT_300] = (int) (78 - (overallDifficulty * 6)); @@ -1511,6 +1516,14 @@ public class Game extends BasicGameState { // difficulty multiplier (scoring) data.calculateDifficultyMultiplier(beatmap.HPDrainRate, beatmap.circleSize, beatmap.overallDifficulty); + + // hit object fade-in time (TODO: formula) + fadeInTime = Math.min(375, (int) (approachTime / 2.5f)); + + // fade times ("Hidden" mod) + // TODO: find the actual formulas for this + hiddenDecayTime = (int) (approachTime / 3.6f); + hiddenTimeDiff = (int) (approachTime / 3.3f); } /** @@ -1534,10 +1547,21 @@ public class Game extends BasicGameState { */ public int getApproachTime() { return approachTime; } + /** + * Returns the amount of time for hit objects to fade in, in milliseconds. + */ + public int getFadeInTime() { return fadeInTime; } + /** * Returns the object decay time in the "Hidden" mod, in milliseconds. */ - public int getDecayTime() { return decayTime; } + public int getHiddenDecayTime() { return hiddenDecayTime; } + + /** + * Returns the time before the hit object time by which the objects have + * completely faded in the "Hidden" mod, in milliseconds. + */ + public int getHiddenTimeDiff() { return hiddenTimeDiff; } /** * Returns an array of hit result offset times, in milliseconds (indexed by GameData.HIT_* constants).