1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-28 00:03:20 +08:00

Merge pull request #10508 from peppy/skinnable-score-display

Add legacy skinning support for score display
This commit is contained in:
Dan Balasescu 2020-10-15 20:28:17 +09:00 committed by GitHub
commit 4c774439b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 242 additions and 73 deletions

View File

@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
int numerator = 0, denominator = 0;
ScoreCounter score = new ScoreCounter(7)
ScoreCounter score = new DefaultScoreCounter
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,

View File

@ -0,0 +1,47 @@
// 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.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Play.HUD;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneSkinnableScoreCounter : SkinnableTestScene
{
private IEnumerable<SkinnableScoreCounter> scoreCounters => CreatedDrawables.OfType<SkinnableScoreCounter>();
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
[SetUpSteps]
public void SetUpSteps()
{
AddStep("Create combo counters", () => SetContents(() =>
{
var comboCounter = new SkinnableScoreCounter();
comboCounter.Current.Value = 1;
return comboCounter;
}));
}
[Test]
public void TestScoreCounterIncrementing()
{
AddStep(@"Reset all", delegate
{
foreach (var s in scoreCounters)
s.Current.Value = 0;
});
AddStep(@"Hit! :D", delegate
{
foreach (var s in scoreCounters)
s.Current.Value += 300;
});
}
}
}

View File

@ -1,18 +1,21 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Play.HUD;
namespace osu.Game.Graphics.UserInterface
{
public class ScoreCounter : RollingCounter<double>
public abstract class ScoreCounter : RollingCounter<double>, IScoreCounter
{
protected override double RollingDuration => 1000;
protected override Easing RollingEasing => Easing.Out;
public bool UseCommaSeparator;
/// <summary>
/// Whether comma separators should be displayed.
/// </summary>
public bool UseCommaSeparator { get; }
/// <summary>
/// How many leading zeroes the counter has.
@ -23,14 +26,13 @@ namespace osu.Game.Graphics.UserInterface
/// Displays score.
/// </summary>
/// <param name="leading">How many leading zeroes the counter will have.</param>
public ScoreCounter(uint leading = 0)
/// <param name="useCommaSeparator">Whether comma separators should be displayed.</param>
protected ScoreCounter(uint leading = 0, bool useCommaSeparator = false)
{
UseCommaSeparator = useCommaSeparator;
LeadingZeroes = leading;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours) => Colour = colours.BlueLighter;
protected override double GetProportionalDuration(double currentValue, double newValue)
{
return currentValue > newValue ? currentValue - newValue : newValue - currentValue;

View File

@ -32,10 +32,10 @@ namespace osu.Game.Screens.Play.HUD
{
base.Update();
if (hud != null)
if (hud?.ScoreCounter.Drawable is DefaultScoreCounter score)
{
// for now align with the score counter. eventually this will be user customisable.
Position = Parent.ToLocalSpace(hud.ScoreCounter.ScreenSpaceDrawQuad.TopRight) + offset;
Position = Parent.ToLocalSpace(score.ScreenSpaceDrawQuad.TopRight) + offset;
}
}

View File

@ -0,0 +1,35 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Play.HUD
{
public class DefaultScoreCounter : ScoreCounter
{
public DefaultScoreCounter()
: base(6)
{
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
}
[Resolved(canBeNull: true)]
private HUDOverlay hud { get; set; }
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Colour = colours.BlueLighter;
// todo: check if default once health display is skinnable
hud?.ShowHealthbar.BindValueChanged(healthBar =>
{
this.MoveToY(healthBar.NewValue ? 30 : 0, HUDOverlay.FADE_DURATION, HUDOverlay.FADE_EASING);
}, true);
}
}
}

View File

@ -0,0 +1,19 @@
// 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.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Play.HUD
{
/// <summary>
/// An interface providing a set of methods to update a score counter.
/// </summary>
public interface IScoreCounter : IDrawable
{
/// <summary>
/// The current score to be displayed.
/// </summary>
Bindable<double> Current { get; }
}
}

View File

@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play.HUD
Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft;
Margin = new MarginPadding { Bottom = 10, Left = 10 };
Margin = new MarginPadding(10);
Scale = new Vector2(1.2f);
}

View File

@ -48,22 +48,29 @@ namespace osu.Game.Screens.Play.HUD
{
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
Child = new FillFlowContainer
{
iconsContainer = new ReverseChildIDFillFlowContainer<ModIcon>
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
iconsContainer = new ReverseChildIDFillFlowContainer<ModIcon>
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
},
unrankedText = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = @"/ UNRANKED /",
Font = OsuFont.Numeric.With(size: 12)
}
},
unrankedText = new OsuSpriteText
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.TopCentre,
Text = @"/ UNRANKED /",
Font = OsuFont.Numeric.With(size: 12)
}
};
Current.ValueChanged += mods =>

View File

@ -20,14 +20,13 @@ namespace osu.Game.Screens.Play.HUD
public readonly VisualSettings VisualSettings;
//public readonly CollectionSettings CollectionSettings;
//public readonly DiscussionSettings DiscussionSettings;
public PlayerSettingsOverlay()
{
AlwaysPresent = true;
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.TopRight;
Origin = Anchor.TopRight;
AutoSizeAxes = Axes.Both;
Child = new FillFlowContainer<PlayerSettingsGroup>
{
@ -36,7 +35,6 @@ namespace osu.Game.Screens.Play.HUD
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 20),
Margin = new MarginPadding { Top = 100, Right = 10 },
Children = new PlayerSettingsGroup[]
{
//CollectionSettings = new CollectionSettings(),

View File

@ -0,0 +1,29 @@
// 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.Bindables;
using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD
{
public class SkinnableScoreCounter : SkinnableDrawable, IScoreCounter
{
public Bindable<double> Current { get; } = new Bindable<double>();
public SkinnableScoreCounter()
: base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter())
{
CentreComponent = false;
}
private IScoreCounter skinnedCounter;
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
skinnedCounter = Drawable as IScoreCounter;
skinnedCounter?.Current.BindTo(Current);
}
}
}

View File

@ -25,12 +25,13 @@ namespace osu.Game.Screens.Play
[Cached]
public class HUDOverlay : Container
{
private const float fade_duration = 400;
private const Easing fade_easing = Easing.Out;
public const float FADE_DURATION = 400;
public const Easing FADE_EASING = Easing.Out;
public readonly KeyCounterDisplay KeyCounter;
public readonly SkinnableComboCounter ComboCounter;
public readonly ScoreCounter ScoreCounter;
public readonly SkinnableScoreCounter ScoreCounter;
public readonly RollingCounter<double> AccuracyCounter;
public readonly HealthDisplay HealthDisplay;
public readonly SongProgress Progress;
@ -62,9 +63,8 @@ namespace osu.Game.Screens.Play
public Action<double> RequestSeek;
private readonly Container topScoreContainer;
private readonly FillFlowContainer bottomRightElements;
private readonly FillFlowContainer topRightElements;
private IEnumerable<Drawable> hideTargets => new Drawable[] { visibilityContainer, KeyCounter };
@ -96,21 +96,10 @@ namespace osu.Game.Screens.Play
Children = new Drawable[]
{
HealthDisplay = CreateHealthDisplay(),
topScoreContainer = new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
},
},
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(),
ModDisplay = CreateModsContainer(),
HitErrorDisplay = CreateHitErrorDisplayOverlay(),
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
}
},
},
@ -126,14 +115,29 @@ namespace osu.Game.Screens.Play
}
},
},
topRightElements = new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Margin = new MarginPadding(10),
Spacing = new Vector2(10),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
ModDisplay = CreateModsContainer(),
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
}
},
bottomRightElements = new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
X = -5,
Margin = new MarginPadding(10),
Spacing = new Vector2(10),
AutoSizeAxes = Axes.Both,
LayoutDuration = fade_duration / 2,
LayoutEasing = fade_easing,
LayoutDuration = FADE_DURATION / 2,
LayoutEasing = FADE_EASING,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
@ -186,21 +190,8 @@ namespace osu.Game.Screens.Play
{
base.LoadComplete();
ShowHud.BindValueChanged(visible => hideTargets.ForEach(d => d.FadeTo(visible.NewValue ? 1 : 0, fade_duration, fade_easing)));
ShowHealthbar.BindValueChanged(healthBar =>
{
if (healthBar.NewValue)
{
HealthDisplay.FadeIn(fade_duration, fade_easing);
topScoreContainer.MoveToY(30, fade_duration, fade_easing);
}
else
{
HealthDisplay.FadeOut(fade_duration, fade_easing);
topScoreContainer.MoveToY(0, fade_duration, fade_easing);
}
}, true);
ShowHealthbar.BindValueChanged(healthBar => HealthDisplay.FadeTo(healthBar.NewValue ? 1 : 0, FADE_DURATION, FADE_EASING), true);
ShowHud.BindValueChanged(visible => hideTargets.ForEach(d => d.FadeTo(visible.NewValue ? 1 : 0, FADE_DURATION, FADE_EASING)));
configShowHud.BindValueChanged(visible =>
{
@ -214,6 +205,8 @@ namespace osu.Game.Screens.Play
protected override void Update()
{
base.Update();
topRightElements.Y = ToLocalSpace(ScoreCounter.Drawable.ScreenSpaceDrawQuad.BottomRight).Y;
bottomRightElements.Y = -Progress.Height;
}
@ -269,11 +262,7 @@ namespace osu.Game.Screens.Play
Margin = new MarginPadding { Top = 5, Right = 20 },
};
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
};
protected virtual SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter();
protected virtual SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter();
@ -293,7 +282,6 @@ namespace osu.Game.Screens.Play
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
};
protected virtual SongProgress CreateProgress() => new SongProgress
@ -314,7 +302,6 @@ namespace osu.Game.Screens.Play
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 20, Right = 20 },
};
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset?.FirstAvailableHitWindows);

View File

@ -6,5 +6,6 @@ namespace osu.Game.Skinning
public enum HUDSkinComponents
{
ComboCounter,
ScoreCounter
}
}

View File

@ -0,0 +1,41 @@
// 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.Bindables;
using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Skinning
{
public class LegacyScoreCounter : ScoreCounter
{
private readonly ISkin skin;
protected override double RollingDuration => 1000;
protected override Easing RollingEasing => Easing.Out;
public new Bindable<double> Current { get; } = new Bindable<double>();
public LegacyScoreCounter(ISkin skin)
: base(6)
{
Anchor = Anchor.TopRight;
Origin = Anchor.TopRight;
this.skin = skin;
// base class uses int for display, but externally we bind to ScoreProcesssor as a double for now.
Current.BindValueChanged(v => base.Current.Value = (int)v.NewValue);
Margin = new MarginPadding(10);
}
protected sealed override OsuSpriteText CreateSpriteText() =>
new LegacySpriteText(skin, "score" /*, true*/)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
};
}
}

View File

@ -341,6 +341,9 @@ namespace osu.Game.Skinning
{
case HUDSkinComponents.ComboCounter:
return new LegacyComboCounter();
case HUDSkinComponents.ScoreCounter:
return new LegacyScoreCounter(this);
}
return null;