mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Adjust namespaces.
Also adds transition, uses IHasCurrentValue, combines Mod TestCases and more.
This commit is contained in:
234
osu.Game/Screens/Play/HUD/ComboCounter.cs
Normal file
234
osu.Game/Screens/Play/HUD/ComboCounter.cs
Normal file
@ -0,0 +1,234 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public abstract class ComboCounter : Container
|
||||
{
|
||||
public BindableInt Current = new BindableInt
|
||||
{
|
||||
MinValue = 0,
|
||||
};
|
||||
|
||||
public bool IsRolling { get; protected set; }
|
||||
|
||||
protected SpriteText PopOutCount;
|
||||
|
||||
protected virtual double PopOutDuration => 150;
|
||||
protected virtual float PopOutScale => 2.0f;
|
||||
protected virtual EasingTypes PopOutEasing => EasingTypes.None;
|
||||
protected virtual float PopOutInitialAlpha => 0.75f;
|
||||
|
||||
protected virtual double FadeOutDuration => 100;
|
||||
|
||||
/// <summary>
|
||||
/// Duration in milliseconds for the counter roll-up animation for each element.
|
||||
/// </summary>
|
||||
protected virtual double RollingDuration => 20;
|
||||
|
||||
/// <summary>
|
||||
/// Easing for the counter rollover animation.
|
||||
/// </summary>
|
||||
protected EasingTypes RollingEasing => EasingTypes.None;
|
||||
|
||||
protected SpriteText DisplayedCountSpriteText;
|
||||
|
||||
private int previousValue;
|
||||
|
||||
/// <summary>
|
||||
/// Base of all combo counters.
|
||||
/// </summary>
|
||||
protected ComboCounter()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
DisplayedCountSpriteText = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
},
|
||||
PopOutCount = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
Margin = new MarginPadding(0.05f),
|
||||
}
|
||||
};
|
||||
|
||||
TextSize = 80;
|
||||
|
||||
Current.ValueChanged += newValue => updateCount(newValue == 0);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
DisplayedCountSpriteText.Text = FormatCount(Current);
|
||||
DisplayedCountSpriteText.Anchor = Anchor;
|
||||
DisplayedCountSpriteText.Origin = Origin;
|
||||
|
||||
StopRolling();
|
||||
}
|
||||
|
||||
private int displayedCount;
|
||||
/// <summary>
|
||||
/// Value shown at the current moment.
|
||||
/// </summary>
|
||||
public virtual int DisplayedCount
|
||||
{
|
||||
get { return displayedCount; }
|
||||
protected set
|
||||
{
|
||||
if (displayedCount.Equals(value))
|
||||
return;
|
||||
updateDisplayedCount(displayedCount, value, IsRolling);
|
||||
}
|
||||
}
|
||||
|
||||
private float textSize;
|
||||
public float TextSize
|
||||
{
|
||||
get { return textSize; }
|
||||
set
|
||||
{
|
||||
textSize = value;
|
||||
DisplayedCountSpriteText.TextSize = TextSize;
|
||||
PopOutCount.TextSize = TextSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments the combo by an amount.
|
||||
/// </summary>
|
||||
/// <param name="amount"></param>
|
||||
public void Increment(int amount = 1)
|
||||
{
|
||||
Current.Value = Current + amount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops rollover animation, forcing the displayed count to be the actual count.
|
||||
/// </summary>
|
||||
public void StopRolling()
|
||||
{
|
||||
updateCount(false);
|
||||
}
|
||||
|
||||
protected virtual string FormatCount(int count)
|
||||
{
|
||||
return count.ToString();
|
||||
}
|
||||
|
||||
protected virtual void OnCountRolling(int currentValue, int newValue)
|
||||
{
|
||||
transformRoll(new TransformComboRoll(), currentValue, newValue);
|
||||
}
|
||||
|
||||
protected virtual void OnCountIncrement(int currentValue, int newValue)
|
||||
{
|
||||
DisplayedCount = newValue;
|
||||
}
|
||||
|
||||
protected virtual void OnCountChange(int currentValue, int newValue)
|
||||
{
|
||||
DisplayedCount = newValue;
|
||||
}
|
||||
|
||||
private double getProportionalDuration(int currentValue, int newValue)
|
||||
{
|
||||
double difference = currentValue > newValue ? currentValue - newValue : newValue - currentValue;
|
||||
return difference * RollingDuration;
|
||||
}
|
||||
|
||||
private void updateDisplayedCount(int currentValue, int newValue, bool rolling)
|
||||
{
|
||||
displayedCount = newValue;
|
||||
if (rolling)
|
||||
OnDisplayedCountRolling(currentValue, newValue);
|
||||
else if (currentValue + 1 == newValue)
|
||||
OnDisplayedCountIncrement(newValue);
|
||||
else
|
||||
OnDisplayedCountChange(newValue);
|
||||
}
|
||||
|
||||
private void updateCount(bool rolling)
|
||||
{
|
||||
int prev = previousValue;
|
||||
previousValue = Current;
|
||||
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
if (!rolling)
|
||||
{
|
||||
Flush(false, typeof(TransformComboRoll));
|
||||
IsRolling = false;
|
||||
DisplayedCount = prev;
|
||||
|
||||
if (prev + 1 == Current)
|
||||
OnCountIncrement(prev, Current);
|
||||
else
|
||||
OnCountChange(prev, Current);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCountRolling(displayedCount, Current);
|
||||
IsRolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void transformRoll(TransformComboRoll transform, int currentValue, int newValue)
|
||||
{
|
||||
Flush(false, typeof(TransformComboRoll));
|
||||
|
||||
if (RollingDuration < 1)
|
||||
{
|
||||
DisplayedCount = Current;
|
||||
return;
|
||||
}
|
||||
|
||||
transform.StartTime = Time.Current;
|
||||
transform.EndTime = Time.Current + getProportionalDuration(currentValue, newValue);
|
||||
transform.StartValue = currentValue;
|
||||
transform.EndValue = newValue;
|
||||
transform.Easing = RollingEasing;
|
||||
|
||||
Transforms.Add(transform);
|
||||
}
|
||||
|
||||
protected class TransformComboRoll : Transform<int>
|
||||
{
|
||||
public override int CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
double time = Time?.Current ?? 0;
|
||||
if (time < StartTime) return StartValue;
|
||||
if (time >= EndTime) return EndValue;
|
||||
|
||||
return (int)Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(Drawable d)
|
||||
{
|
||||
base.Apply(d);
|
||||
((ComboCounter)d).DisplayedCount = CurrentValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void OnDisplayedCountRolling(int currentValue, int newValue);
|
||||
protected abstract void OnDisplayedCountIncrement(int newValue);
|
||||
protected abstract void OnDisplayedCountChange(int newValue);
|
||||
}
|
||||
}
|
58
osu.Game/Screens/Play/HUD/ComboResultCounter.cs
Normal file
58
osu.Game/Screens/Play/HUD/ComboResultCounter.cs
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to display combo with a roll-up animation in results screen.
|
||||
/// </summary>
|
||||
public class ComboResultCounter : RollingCounter<ulong>
|
||||
{
|
||||
protected override Type TransformType => typeof(TransformComboResult);
|
||||
|
||||
protected override double RollingDuration => 500;
|
||||
protected override EasingTypes RollingEasing => EasingTypes.Out;
|
||||
|
||||
protected override double GetProportionalDuration(ulong currentValue, ulong newValue)
|
||||
{
|
||||
return currentValue > newValue ? currentValue - newValue : newValue - currentValue;
|
||||
}
|
||||
|
||||
protected override string FormatCount(ulong count)
|
||||
{
|
||||
return $@"{count}x";
|
||||
}
|
||||
|
||||
public override void Increment(ulong amount)
|
||||
{
|
||||
Current.Value = Current + amount;
|
||||
}
|
||||
|
||||
protected class TransformComboResult : Transform<ulong>
|
||||
{
|
||||
public override ulong CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
double time = Time?.Current ?? 0;
|
||||
if (time < StartTime) return StartValue;
|
||||
if (time >= EndTime) return EndValue;
|
||||
|
||||
return (ulong)Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(Drawable d)
|
||||
{
|
||||
base.Apply(d);
|
||||
((ComboResultCounter)d).DisplayedCount = CurrentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
osu.Game/Screens/Play/HUD/HealthDisplay.cs
Normal file
24
osu.Game/Screens/Play/HUD/HealthDisplay.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public abstract class HealthDisplay : Container
|
||||
{
|
||||
public readonly BindableDouble Current = new BindableDouble
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 1
|
||||
};
|
||||
|
||||
protected HealthDisplay()
|
||||
{
|
||||
Current.ValueChanged += newValue => SetHealth((float)newValue);
|
||||
}
|
||||
|
||||
protected abstract void SetHealth(float value);
|
||||
}
|
||||
}
|
105
osu.Game/Screens/Play/HUD/ModDisplay.cs
Normal file
105
osu.Game/Screens/Play/HUD/ModDisplay.cs
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class ModDisplay : Container, IHasCurrentValue<IEnumerable<Mod>>
|
||||
{
|
||||
private readonly Bindable<IEnumerable<Mod>> mods = new Bindable<IEnumerable<Mod>>();
|
||||
|
||||
private bool showMods;
|
||||
public bool ShowMods
|
||||
{
|
||||
get
|
||||
{
|
||||
return showMods;
|
||||
}
|
||||
set
|
||||
{
|
||||
showMods = value;
|
||||
if (!showMods)
|
||||
Hide();
|
||||
else
|
||||
Show();
|
||||
}
|
||||
}
|
||||
|
||||
public Bindable<IEnumerable<Mod>> Current => mods;
|
||||
|
||||
private readonly FillFlowContainer<ModIcon> iconsContainer;
|
||||
|
||||
public ModDisplay()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
iconsContainer = new IconFlow
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Margin = new MarginPadding { Left = 10, Right = 10 },
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = @"/ UNRANKED /",
|
||||
Font = @"Venera",
|
||||
TextSize = 12,
|
||||
}
|
||||
};
|
||||
|
||||
mods.ValueChanged += mods =>
|
||||
{
|
||||
iconsContainer.Clear();
|
||||
foreach (Mod mod in mods)
|
||||
{
|
||||
iconsContainer.Add(new ModIcon(mod)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.6f),
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
if (IsLoaded)
|
||||
appearTransform();
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
appearTransform();
|
||||
}
|
||||
|
||||
private void appearTransform()
|
||||
{
|
||||
iconsContainer.Flush();
|
||||
iconsContainer.FadeInFromZero(1000, EasingTypes.OutQuint);
|
||||
iconsContainer.TransformSpacingTo(new Vector2(5, 0));
|
||||
using (iconsContainer.BeginDelayedSequence(1200))
|
||||
iconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, EasingTypes.OutQuint);
|
||||
}
|
||||
|
||||
private class IconFlow : FillFlowContainer<ModIcon>
|
||||
{
|
||||
// just reverses the depth of flow contents.
|
||||
protected override IComparer<Drawable> DepthComparer => new ReverseCreationOrderDepthComparer();
|
||||
protected override IEnumerable<ModIcon> FlowingChildren => base.FlowingChildren.Reverse();
|
||||
}
|
||||
}
|
||||
}
|
140
osu.Game/Screens/Play/HUD/StandardComboCounter.cs
Normal file
140
osu.Game/Screens/Play/HUD/StandardComboCounter.cs
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// Uses the 'x' symbol and has a pop-out effect while rolling over.
|
||||
/// </summary>
|
||||
public class StandardComboCounter : ComboCounter
|
||||
{
|
||||
protected uint ScheduledPopOutCurrentId;
|
||||
|
||||
protected virtual float PopOutSmallScale => 1.1f;
|
||||
protected virtual bool CanPopOutWhileRolling => false;
|
||||
|
||||
public new Vector2 PopOutScale = new Vector2(1.6f);
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
PopOutCount.Origin = Origin;
|
||||
PopOutCount.Anchor = Anchor;
|
||||
}
|
||||
|
||||
protected override string FormatCount(int count)
|
||||
{
|
||||
return $@"{count}x";
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOut(int newValue)
|
||||
{
|
||||
PopOutCount.Text = FormatCount(newValue);
|
||||
|
||||
PopOutCount.ScaleTo(PopOutScale);
|
||||
PopOutCount.FadeTo(PopOutInitialAlpha);
|
||||
PopOutCount.MoveTo(Vector2.Zero);
|
||||
|
||||
PopOutCount.ScaleTo(1, PopOutDuration, PopOutEasing);
|
||||
PopOutCount.FadeOut(PopOutDuration, PopOutEasing);
|
||||
PopOutCount.MoveTo(DisplayedCountSpriteText.Position, PopOutDuration, PopOutEasing);
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOutRolling(int newValue)
|
||||
{
|
||||
TransformPopOut(newValue);
|
||||
TransformPopOutSmall(newValue);
|
||||
}
|
||||
|
||||
protected virtual void TransformNoPopOut(int newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(1);
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOutSmall(int newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(PopOutSmallScale);
|
||||
DisplayedCountSpriteText.ScaleTo(1, PopOutDuration, PopOutEasing);
|
||||
}
|
||||
|
||||
protected virtual void ScheduledPopOutSmall(uint id)
|
||||
{
|
||||
// Too late; scheduled task invalidated
|
||||
if (id != ScheduledPopOutCurrentId)
|
||||
return;
|
||||
|
||||
DisplayedCount++;
|
||||
}
|
||||
|
||||
protected override void OnCountRolling(int currentValue, int newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
// Hides displayed count if was increasing from 0 to 1 but didn't finish
|
||||
if (currentValue == 0 && newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
|
||||
|
||||
base.OnCountRolling(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnCountIncrement(int currentValue, int newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
if (DisplayedCount < currentValue)
|
||||
DisplayedCount++;
|
||||
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformPopOut(newValue);
|
||||
|
||||
uint newTaskId = ScheduledPopOutCurrentId;
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
ScheduledPopOutSmall(newTaskId);
|
||||
}, PopOutDuration);
|
||||
}
|
||||
|
||||
protected override void OnCountChange(int currentValue, int newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
if (newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut();
|
||||
|
||||
base.OnCountChange(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountRolling(int currentValue, int newValue)
|
||||
{
|
||||
if (newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
|
||||
else
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
if (CanPopOutWhileRolling)
|
||||
TransformPopOutRolling(newValue);
|
||||
else
|
||||
TransformNoPopOut(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountChange(int newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.FadeTo(newValue == 0 ? 0 : 1);
|
||||
|
||||
TransformNoPopOut(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountIncrement(int newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformPopOutSmall(newValue);
|
||||
}
|
||||
}
|
||||
}
|
107
osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs
Normal file
107
osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class StandardHealthDisplay : HealthDisplay, IHasAccentColour
|
||||
{
|
||||
/// <summary>
|
||||
/// The base opacity of the glow.
|
||||
/// </summary>
|
||||
private const float base_glow_opacity = 0.6f;
|
||||
|
||||
/// <summary>
|
||||
/// The number of sequential hits required within <see cref="glow_fade_delay"/> to reach the maximum glow opacity.
|
||||
/// </summary>
|
||||
private const int glow_max_hits = 8;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to delay before fading the glow opacity back to <see cref="base_glow_opacity"/>.
|
||||
/// <para>
|
||||
/// This is calculated to require a stream snapped to 1/4 at 150bpm to reach the maximum glow opacity with <see cref="glow_max_hits"/> hits.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
private const float glow_fade_delay = 100;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to fade the glow to <see cref="base_glow_opacity"/> after <see cref="glow_fade_delay"/>.
|
||||
/// </summary>
|
||||
private const double glow_fade_time = 500;
|
||||
|
||||
private readonly Container fill;
|
||||
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get { return fill.Colour; }
|
||||
set { fill.Colour = value; }
|
||||
}
|
||||
|
||||
private Color4 glowColour;
|
||||
public Color4 GlowColour
|
||||
{
|
||||
get { return glowColour; }
|
||||
set
|
||||
{
|
||||
if (glowColour == value)
|
||||
return;
|
||||
glowColour = value;
|
||||
|
||||
fill.EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Colour = glowColour.Opacity(base_glow_opacity),
|
||||
Radius = 8,
|
||||
Roundness = 4,
|
||||
Type = EdgeEffectType.Glow,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public StandardHealthDisplay()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
fill = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0, 1),
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public void Flash(Judgement judgement)
|
||||
{
|
||||
if (judgement.Result == HitResult.Miss)
|
||||
return;
|
||||
|
||||
fill.FadeEdgeEffectTo(Math.Min(1, fill.EdgeEffect.Colour.Linear.A + (1f - base_glow_opacity) / glow_max_hits), 50, EasingTypes.OutQuint);
|
||||
fill.Delay(glow_fade_delay);
|
||||
fill.FadeEdgeEffectTo(base_glow_opacity, glow_fade_time, EasingTypes.OutQuint);
|
||||
}
|
||||
|
||||
protected override void SetHealth(float value) => fill.ResizeTo(new Vector2(value, 1), 200, EasingTypes.OutQuint);
|
||||
}
|
||||
}
|
131
osu.Game/Screens/Play/HUDOverlay.cs
Normal file
131
osu.Game/Screens/Play/HUDOverlay.cs
Normal file
@ -0,0 +1,131 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public abstract class HUDOverlay : Container
|
||||
{
|
||||
private const int duration = 100;
|
||||
|
||||
private readonly Container content;
|
||||
public readonly KeyCounterCollection KeyCounter;
|
||||
public readonly RollingCounter<int> ComboCounter;
|
||||
public readonly ScoreCounter ScoreCounter;
|
||||
public readonly RollingCounter<double> AccuracyCounter;
|
||||
public readonly HealthDisplay HealthDisplay;
|
||||
public readonly SongProgress Progress;
|
||||
public readonly ModDisplay ModDisplay;
|
||||
|
||||
private Bindable<bool> showKeyCounter;
|
||||
private Bindable<bool> showHud;
|
||||
|
||||
private static bool hasShownNotificationOnce;
|
||||
|
||||
protected abstract KeyCounterCollection CreateKeyCounter();
|
||||
protected abstract RollingCounter<int> CreateComboCounter();
|
||||
protected abstract RollingCounter<double> CreateAccuracyCounter();
|
||||
protected abstract ScoreCounter CreateScoreCounter();
|
||||
protected abstract HealthDisplay CreateHealthDisplay();
|
||||
protected abstract SongProgress CreateProgress();
|
||||
protected abstract ModDisplay CreateModsContainer();
|
||||
|
||||
protected HUDOverlay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Add(content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
ComboCounter = CreateComboCounter(),
|
||||
ScoreCounter = CreateScoreCounter(),
|
||||
AccuracyCounter = CreateAccuracyCounter(),
|
||||
HealthDisplay = CreateHealthDisplay(),
|
||||
Progress = CreateProgress(),
|
||||
ModDisplay = CreateModsContainer(),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuConfigManager config, NotificationManager notificationManager)
|
||||
{
|
||||
showKeyCounter = config.GetBindable<bool>(OsuConfig.KeyOverlay);
|
||||
showKeyCounter.ValueChanged += keyCounterVisibility =>
|
||||
{
|
||||
if (keyCounterVisibility)
|
||||
KeyCounter.FadeIn(duration);
|
||||
else
|
||||
KeyCounter.FadeOut(duration);
|
||||
};
|
||||
showKeyCounter.TriggerChange();
|
||||
|
||||
showHud = config.GetBindable<bool>(OsuConfig.ShowInterface);
|
||||
showHud.ValueChanged += hudVisibility =>
|
||||
{
|
||||
if (hudVisibility)
|
||||
content.FadeIn(duration);
|
||||
else
|
||||
content.FadeOut(duration);
|
||||
};
|
||||
showHud.TriggerChange();
|
||||
|
||||
if (!showHud && !hasShownNotificationOnce)
|
||||
{
|
||||
hasShownNotificationOnce = true;
|
||||
|
||||
notificationManager?.Post(new SimpleNotification
|
||||
{
|
||||
Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BindProcessor(ScoreProcessor processor)
|
||||
{
|
||||
ScoreCounter?.Current.BindTo(processor.TotalScore);
|
||||
AccuracyCounter?.Current.BindTo(processor.Accuracy);
|
||||
ComboCounter?.Current.BindTo(processor.Combo);
|
||||
HealthDisplay?.Current.BindTo(processor.Health);
|
||||
}
|
||||
|
||||
public virtual void BindHitRenderer(HitRenderer hitRenderer)
|
||||
{
|
||||
hitRenderer.InputManager.Add(KeyCounter.GetReceptor());
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
if (args.Repeat) return false;
|
||||
|
||||
if (state.Keyboard.ShiftPressed)
|
||||
{
|
||||
switch (args.Key)
|
||||
{
|
||||
case Key.Tab:
|
||||
showHud.Value = !showHud.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnKeyDown(state, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Configuration;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class ModsContainer : Container
|
||||
{
|
||||
public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
|
||||
|
||||
private bool showMods;
|
||||
public bool ShowMods
|
||||
{
|
||||
get
|
||||
{
|
||||
return showMods;
|
||||
}
|
||||
set
|
||||
{
|
||||
showMods = value;
|
||||
if (!showMods)
|
||||
Hide();
|
||||
else
|
||||
Show();
|
||||
}
|
||||
}
|
||||
|
||||
public ModsContainer()
|
||||
{
|
||||
FillFlowContainer<ModIcon> iconsContainer;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
iconsContainer = new FillFlowContainer<ModIcon>
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5,0),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = @"/ UNRANKED /",
|
||||
Font = @"Venera",
|
||||
TextSize = 12,
|
||||
}
|
||||
};
|
||||
|
||||
Mods.ValueChanged += mods =>
|
||||
{
|
||||
iconsContainer.Clear();
|
||||
foreach (Mod mod in mods)
|
||||
{
|
||||
iconsContainer.Add(new ModIcon(mod)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.65f),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -72,7 +72,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private Container hitRendererContainer;
|
||||
|
||||
private HudOverlay hudOverlay;
|
||||
private HUDOverlay hudOverlay;
|
||||
private PauseOverlay pauseOverlay;
|
||||
private FailOverlay failOverlay;
|
||||
|
||||
@ -154,7 +154,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
scoreProcessor = HitRenderer.CreateScoreProcessor();
|
||||
|
||||
hudOverlay = new StandardHudOverlay()
|
||||
hudOverlay = new StandardHUDOverlay()
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
@ -169,8 +169,8 @@ namespace osu.Game.Screens.Play
|
||||
hudOverlay.Progress.AllowSeeking = HitRenderer.HasReplayLoaded;
|
||||
hudOverlay.Progress.OnSeek = pos => decoupledClock.Seek(pos);
|
||||
|
||||
hudOverlay.ModsContainer.ShowMods = HitRenderer.HasReplayLoaded;
|
||||
hudOverlay.ModsContainer.Mods.BindTo(Beatmap.Mods);
|
||||
hudOverlay.ModDisplay.ShowMods = HitRenderer.HasReplayLoaded;
|
||||
hudOverlay.ModDisplay.Current.BindTo(Beatmap.Mods);
|
||||
|
||||
//bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
|
||||
HitRenderer.OnAllJudged += onCompletion;
|
||||
|
99
osu.Game/Screens/Play/StandardHudOverlay.cs
Normal file
99
osu.Game/Screens/Play/StandardHudOverlay.cs
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class StandardHUDOverlay : HUDOverlay
|
||||
{
|
||||
protected override RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopRight,
|
||||
Position = new Vector2(0, 35),
|
||||
TextSize = 20,
|
||||
Margin = new MarginPadding { Right = 140 },
|
||||
};
|
||||
|
||||
protected override RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopLeft,
|
||||
Position = new Vector2(0, 35),
|
||||
Margin = new MarginPadding { Left = 140 },
|
||||
TextSize = 20,
|
||||
};
|
||||
|
||||
protected override HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
|
||||
{
|
||||
Size = new Vector2(1, 5),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Margin = new MarginPadding { Top = 20 }
|
||||
};
|
||||
|
||||
protected override KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection
|
||||
{
|
||||
IsCounting = true,
|
||||
FadeTime = 50,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Margin = new MarginPadding(10),
|
||||
Y = - TwoLayerButton.SIZE_RETRACTED.Y,
|
||||
};
|
||||
|
||||
protected override ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
TextSize = 40,
|
||||
Position = new Vector2(0, 30),
|
||||
};
|
||||
|
||||
protected override SongProgress CreateProgress() => new SongProgress
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
};
|
||||
|
||||
protected override ModDisplay CreateModsContainer() => new ModDisplay
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Top = 20, Right = 10 },
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
ComboCounter.AccentColour = colours.BlueLighter;
|
||||
AccuracyCounter.AccentColour = colours.BlueLighter;
|
||||
ScoreCounter.AccentColour = colours.BlueLighter;
|
||||
|
||||
var shd = HealthDisplay as StandardHealthDisplay;
|
||||
if (shd != null)
|
||||
{
|
||||
shd.AccentColour = colours.BlueLighter;
|
||||
shd.GlowColour = colours.BlueDarker;
|
||||
}
|
||||
}
|
||||
|
||||
public override void BindProcessor(ScoreProcessor processor)
|
||||
{
|
||||
base.BindProcessor(processor);
|
||||
|
||||
var shd = HealthDisplay as StandardHealthDisplay;
|
||||
if (shd != null)
|
||||
processor.NewJudgement += shd.Flash;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user