From 9c31cd63ba31d94797c0a02a3f79f8896af9b935 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 25 Feb 2017 23:35:51 +0100 Subject: [PATCH 1/3] slider follow circle start/end animations (itdelatrisu/opsu@99c698b) --- src/itdelatrisu/opsu/GameData.java | 13 ++++++++++ src/itdelatrisu/opsu/objects/Slider.java | 30 ++++++++++++++++++++---- src/org/newdawn/slick/Image.java | 3 ++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 9138d725..2b790bcb 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -60,6 +60,8 @@ public class GameData { /** Time, in milliseconds, for a hit circle to fade. */ public static final int HITCIRCLE_FADE_TIME = 300; + public static final int FOLLOWCIRCLE_FADE_TIME = HITCIRCLE_FADE_TIME / 2; + /** Duration, in milliseconds, of a combo pop effect. */ private static final int COMBO_POP_TIME = 250; @@ -991,6 +993,17 @@ public class GameData { return; } + // slider follow circle + if (hitResult.expand && ( + hitResult.hitResultType == HitObjectType.SLIDER_FIRST || hitResult.hitResultType == HitObjectType.SLIDER_LAST)) { + float progress = AnimationEquation.OUT_CUBIC.calc((float) Utils.clamp(trackPosition - hitResult.time, 0, FOLLOWCIRCLE_FADE_TIME) / FOLLOWCIRCLE_FADE_TIME); + float scale = 1f - 0.2f * progress; + float alpha = 1f - progress; + Image fc = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(scale); + fc.setAlpha(alpha); + fc.drawCentered(hitResult.x, hitResult.y); + } + // hit circles float progress = AnimationEquation.OUT_CUBIC.calc( (float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME); diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 6ffaee19..f661c523 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -33,7 +33,6 @@ import itdelatrisu.opsu.ui.Colors; import itdelatrisu.opsu.ui.animations.AnimationEquation; import org.newdawn.slick.Color; -import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.Image; import yugecin.opsudance.Dancer; @@ -110,8 +109,12 @@ public class Slider extends GameObject { /** The current tick time for the follow circle expanding animation. */ private int tickExpandTime = 0; + private int followExpandTime = 0; + /** The duration of the follow circle expanding animation on ticks. */ private static final int TICK_EXPAND_TIME = 200; + private static final int FOLLOW_EXPAND_TIME = 150; + private static final int FOLLOW_SHRINK_TIME = 100; /** Container dimensions. */ private static int containerWidth, containerHeight; @@ -366,9 +369,25 @@ public class Slider extends GameObject { } // follow circle - if (followCircleActive) { + if (followCircleActive || followExpandTime > 0) { float followCircleScale = 1f + (tickExpandTime / (float) TICK_EXPAND_TIME) * 0.1f; - GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(followCircleScale).drawCentered(c.x, c.y); + float followAlpha = 1f; + if (followCircleActive && followExpandTime < FOLLOW_EXPAND_TIME) { + followExpandTime += DisplayContainer.instance.renderDelta; + followCircleScale *= 0.5f; + float progress = AnimationEquation.OUT_QUAD.calc((float) followExpandTime / FOLLOW_EXPAND_TIME); + followCircleScale = followCircleScale + followCircleScale * progress; + followAlpha = progress; + } else if (!followCircleActive) { + followExpandTime -= DisplayContainer.instance.renderDelta; + if (followExpandTime > FOLLOW_SHRINK_TIME) { + followExpandTime = FOLLOW_SHRINK_TIME; + } + float progress = 1f - AnimationEquation.IN_QUAD.calc((float) followExpandTime / FOLLOW_EXPAND_TIME); + followCircleScale *= progress; + followAlpha = progress; + } + GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(followCircleScale).setAlpha(followAlpha).drawCentered(c.x, c.y); // "flashlight" mod: dim the screen if (GameMod.FLASHLIGHT.isActive()) { @@ -716,7 +735,10 @@ public class Slider extends GameObject { double distance = Math.hypot(c.x - mouseX, c.y - mouseY); if (((keyPressed || GameMod.RELAX.isActive()) && distance < followRadius) || isAutoMod) { // mouse pressed and within follow circle - followCircleActive = true; + if (!followCircleActive) { + followCircleActive = true; + followExpandTime = 0; + } // held during new repeat if (isNewRepeat) { diff --git a/src/org/newdawn/slick/Image.java b/src/org/newdawn/slick/Image.java index 8989fb92..22f8a6c3 100644 --- a/src/org/newdawn/slick/Image.java +++ b/src/org/newdawn/slick/Image.java @@ -981,8 +981,9 @@ public class Image implements Renderable { * * @param alpha The alpha value to use when rendering this image */ - public void setAlpha(float alpha) { + public Image setAlpha(float alpha) { this.alpha = alpha; + return this; } /** From 5ccc863a17c8e635c2445a42004949ce586975c6 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 25 Feb 2017 23:45:22 +0100 Subject: [PATCH 2/3] fix slider followcircle shrink animations showing on repeats --- src/itdelatrisu/opsu/GameData.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 2b790bcb..4ff4e138 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -976,6 +976,17 @@ public class GameData { Colors.WHITE_FADE.a = oldWhiteAlpha; hitResult.color.a = oldColorAlpha; } + + // slider follow circle + if (hitResult.expand) { + float progress = AnimationEquation.OUT_CUBIC.calc((float) Utils.clamp(trackPosition - hitResult.time, 0, FOLLOWCIRCLE_FADE_TIME) / FOLLOWCIRCLE_FADE_TIME); + float scale = 1f - 0.2f * progress; + float alpha = 1f - progress; + Image fc = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(scale); + fc.setAlpha(alpha); + fc.drawCentered(hitResult.x, hitResult.y); + } + if (!Options.isDrawSliderEndCircles()) { return; } @@ -993,17 +1004,6 @@ public class GameData { return; } - // slider follow circle - if (hitResult.expand && ( - hitResult.hitResultType == HitObjectType.SLIDER_FIRST || hitResult.hitResultType == HitObjectType.SLIDER_LAST)) { - float progress = AnimationEquation.OUT_CUBIC.calc((float) Utils.clamp(trackPosition - hitResult.time, 0, FOLLOWCIRCLE_FADE_TIME) / FOLLOWCIRCLE_FADE_TIME); - float scale = 1f - 0.2f * progress; - float alpha = 1f - progress; - Image fc = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(scale); - fc.setAlpha(alpha); - fc.drawCentered(hitResult.x, hitResult.y); - } - // hit circles float progress = AnimationEquation.OUT_CUBIC.calc( (float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME); From e783b4fe3c3b331e66db03e86c1cf9a67457c994 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 25 Feb 2017 23:51:42 +0100 Subject: [PATCH 3/3] workaround for #114 --- src/itdelatrisu/opsu/GameData.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 4ff4e138..58ab4154 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -1025,6 +1025,8 @@ public class GameData { scaledRepeat.rotate(ang); scaledRepeat.drawCentered(hitResult.x, hitResult.y, hitResult.color); if (!Options.isDrawSliderEndCircles()) { + GameImage.HITCIRCLE.getImage().draw(-1000, -1000); // TODO this 'fixes' #114. Why? Get a better solution! + GameImage.HITCIRCLE_OVERLAY.getImage().draw(-1000, -1000); return; } }