Merge pull request #11976 from frenzibyte/legacy-spinner-bonus
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-0.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-1.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-3.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-4.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-5.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-6.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-7.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-8.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-9.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-comma.png
Normal file
After Width: | Height: | Size: 865 B |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-dot.png
Normal file
After Width: | Height: | Size: 771 B |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-percent.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
osu.Game.Rulesets.Osu.Tests/Resources/old-skin/score-x.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
@ -1,2 +1,6 @@
|
|||||||
[General]
|
[General]
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
|
|
||||||
|
[Fonts]
|
||||||
|
HitCircleOverlap: 3
|
||||||
|
ScoreOverlap: 3
|
@ -33,12 +33,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public SpinnerSpmCounter SpmCounter { get; private set; }
|
public SpinnerSpmCounter SpmCounter { get; private set; }
|
||||||
|
|
||||||
private Container<DrawableSpinnerTick> ticks;
|
private Container<DrawableSpinnerTick> ticks;
|
||||||
private SpinnerBonusDisplay bonusDisplay;
|
|
||||||
private PausableSkinnableSound spinningSample;
|
private PausableSkinnableSound spinningSample;
|
||||||
|
|
||||||
private Bindable<bool> isSpinning;
|
private Bindable<bool> isSpinning;
|
||||||
private bool spinnerFrequencyModulate;
|
private bool spinnerFrequencyModulate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of bonus score gained from spinning after the required number of spins, for display purposes.
|
||||||
|
/// </summary>
|
||||||
|
public IBindable<double> GainedBonus => gainedBonus;
|
||||||
|
|
||||||
|
private readonly Bindable<double> gainedBonus = new Bindable<double>();
|
||||||
|
|
||||||
private const double fade_out_duration = 160;
|
private const double fade_out_duration = 160;
|
||||||
|
|
||||||
public DrawableSpinner()
|
public DrawableSpinner()
|
||||||
@ -67,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinnerDisc()),
|
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
|
||||||
RotationTracker = new SpinnerRotationTracker(this)
|
RotationTracker = new SpinnerRotationTracker(this)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -78,12 +84,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Y = 120,
|
Y = 120,
|
||||||
Alpha = 0
|
Alpha = 0
|
||||||
},
|
},
|
||||||
bonusDisplay = new SpinnerBonusDisplay
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Y = -120,
|
|
||||||
},
|
|
||||||
spinningSample = new PausableSkinnableSound
|
spinningSample = new PausableSkinnableSound
|
||||||
{
|
{
|
||||||
Volume = { Value = 0 },
|
Volume = { Value = 0 },
|
||||||
@ -298,6 +298,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private void fadeInCounter() => SpmCounter.FadeIn(HitObject.TimeFadeIn);
|
private void fadeInCounter() => SpmCounter.FadeIn(HitObject.TimeFadeIn);
|
||||||
|
|
||||||
|
private static readonly int score_per_tick = new SpinnerBonusTick.OsuSpinnerBonusTickJudgement().MaxNumericResult;
|
||||||
|
|
||||||
private int wholeSpins;
|
private int wholeSpins;
|
||||||
|
|
||||||
private void updateBonusScore()
|
private void updateBonusScore()
|
||||||
@ -322,8 +324,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (tick != null)
|
if (tick != null)
|
||||||
{
|
{
|
||||||
tick.TriggerResult(true);
|
tick.TriggerResult(true);
|
||||||
|
|
||||||
if (tick is DrawableSpinnerBonusTick)
|
if (tick is DrawableSpinnerBonusTick)
|
||||||
bonusDisplay.SetBonusCount(spins - HitObject.SpinsRequired);
|
gainedBonus.Value = score_per_tick * (spins - HitObject.SpinsRequired);
|
||||||
}
|
}
|
||||||
|
|
||||||
wholeSpins++;
|
wholeSpins++;
|
||||||
|
@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
SliderFollowCircle,
|
SliderFollowCircle,
|
||||||
SliderBall,
|
SliderBall,
|
||||||
SliderBody,
|
SliderBody,
|
||||||
SpinnerBody
|
SpinnerBody,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
68
osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Skinning.Default
|
||||||
|
{
|
||||||
|
public class DefaultSpinner : CompositeDrawable
|
||||||
|
{
|
||||||
|
private DrawableSpinner drawableSpinner;
|
||||||
|
|
||||||
|
private OsuSpriteText bonusCounter;
|
||||||
|
|
||||||
|
public DefaultSpinner()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(DrawableHitObject drawableHitObject)
|
||||||
|
{
|
||||||
|
drawableSpinner = (DrawableSpinner)drawableHitObject;
|
||||||
|
|
||||||
|
AddRangeInternal(new Drawable[]
|
||||||
|
{
|
||||||
|
new DefaultSpinnerDisc
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
},
|
||||||
|
bonusCounter = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Font = OsuFont.Numeric.With(size: 24),
|
||||||
|
Y = -120,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBindable<double> gainedBonus;
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
gainedBonus = drawableSpinner.GainedBonus.GetBoundCopy();
|
||||||
|
gainedBonus.BindValueChanged(bonus =>
|
||||||
|
{
|
||||||
|
bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo);
|
||||||
|
bonusCounter.FadeOutFromOne(1500);
|
||||||
|
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,14 +40,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
|
|
||||||
public DefaultSpinnerDisc()
|
public DefaultSpinnerDisc()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
|
||||||
|
|
||||||
// we are slightly bigger than our parent, to clip the top and bottom of the circle
|
// we are slightly bigger than our parent, to clip the top and bottom of the circle
|
||||||
// this should probably be revisited when scaled spinners are a thing.
|
// this should probably be revisited when scaled spinners are a thing.
|
||||||
Scale = new Vector2(initial_scale);
|
Scale = new Vector2(initial_scale);
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
|
||||||
Origin = Anchor.Centre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Shows incremental bonus score achieved for a spinner.
|
|
||||||
/// </summary>
|
|
||||||
public class SpinnerBonusDisplay : CompositeDrawable
|
|
||||||
{
|
|
||||||
private static readonly int score_per_tick = new SpinnerBonusTick().CreateJudgement().MaxNumericResult;
|
|
||||||
|
|
||||||
private readonly OsuSpriteText bonusCounter;
|
|
||||||
|
|
||||||
public SpinnerBonusDisplay()
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
|
|
||||||
InternalChild = bonusCounter = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Font = OsuFont.Numeric.With(size: 24),
|
|
||||||
Alpha = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private int displayedCount;
|
|
||||||
|
|
||||||
public void SetBonusCount(int count)
|
|
||||||
{
|
|
||||||
if (displayedCount == count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
displayedCount = count;
|
|
||||||
bonusCounter.Text = $"{score_per_tick * count}";
|
|
||||||
bonusCounter.FadeOutFromOne(1500);
|
|
||||||
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -32,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
private Sprite spin;
|
private Sprite spin;
|
||||||
private Sprite clear;
|
private Sprite clear;
|
||||||
|
|
||||||
|
private LegacySpriteText bonusCounter;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(DrawableHitObject drawableHitObject, ISkinSource source)
|
private void load(DrawableHitObject drawableHitObject, ISkinSource source)
|
||||||
{
|
{
|
||||||
@ -45,36 +48,67 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
|
|
||||||
DrawableSpinner = (DrawableSpinner)drawableHitObject;
|
DrawableSpinner = (DrawableSpinner)drawableHitObject;
|
||||||
|
|
||||||
AddRangeInternal(new[]
|
Container overlayContainer;
|
||||||
|
|
||||||
|
AddInternal(overlayContainer = new Container
|
||||||
{
|
{
|
||||||
spin = new Sprite
|
Depth = float.MinValue,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
spin = new Sprite
|
||||||
Origin = Anchor.Centre,
|
{
|
||||||
Depth = float.MinValue,
|
Anchor = Anchor.TopCentre,
|
||||||
Texture = source.GetTexture("spinner-spin"),
|
Origin = Anchor.Centre,
|
||||||
Scale = new Vector2(SPRITE_SCALE),
|
Texture = source.GetTexture("spinner-spin"),
|
||||||
Y = SPINNER_TOP_OFFSET + 335,
|
Scale = new Vector2(SPRITE_SCALE),
|
||||||
},
|
Y = SPINNER_TOP_OFFSET + 335,
|
||||||
clear = new Sprite
|
},
|
||||||
{
|
clear = new Sprite
|
||||||
Alpha = 0,
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Alpha = 0,
|
||||||
Origin = Anchor.Centre,
|
Anchor = Anchor.TopCentre,
|
||||||
Depth = float.MinValue,
|
Origin = Anchor.Centre,
|
||||||
Texture = source.GetTexture("spinner-clear"),
|
Texture = source.GetTexture("spinner-clear"),
|
||||||
Scale = new Vector2(SPRITE_SCALE),
|
Scale = new Vector2(SPRITE_SCALE),
|
||||||
Y = SPINNER_TOP_OFFSET + 115,
|
Y = SPINNER_TOP_OFFSET + 115,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bonusCounter = (source.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText)) as LegacySpriteText)?.With(c =>
|
||||||
|
{
|
||||||
|
c.Alpha = 0f;
|
||||||
|
c.Anchor = Anchor.TopCentre;
|
||||||
|
c.Origin = Anchor.Centre;
|
||||||
|
c.Font = c.Font.With(fixedWidth: false);
|
||||||
|
c.Scale = new Vector2(SPRITE_SCALE);
|
||||||
|
c.Y = SPINNER_TOP_OFFSET + 299;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (bonusCounter != null)
|
||||||
|
overlayContainer.Add(bonusCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IBindable<double> gainedBonus;
|
||||||
|
|
||||||
private readonly Bindable<bool> completed = new Bindable<bool>();
|
private readonly Bindable<bool> completed = new Bindable<bool>();
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
|
if (bonusCounter != null)
|
||||||
|
{
|
||||||
|
gainedBonus = DrawableSpinner.GainedBonus.GetBoundCopy();
|
||||||
|
gainedBonus.BindValueChanged(bonus =>
|
||||||
|
{
|
||||||
|
bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo);
|
||||||
|
bonusCounter.FadeOutFromOne(800, Easing.Out);
|
||||||
|
bonusCounter.ScaleTo(SPRITE_SCALE * 2f).Then().ScaleTo(SPRITE_SCALE * 1.28f, 800, Easing.Out);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
completed.BindValueChanged(onCompletedChanged, true);
|
completed.BindValueChanged(onCompletedChanged, true);
|
||||||
|
|
||||||
DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms;
|
DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms;
|
||||||
|