osu/osu.Game/Screens/Play/HUDOverlay.cs

247 lines
8.9 KiB
C#
Raw Normal View History

2018-04-13 09:19:50 +00:00
// Copyright (c) 2007-2018 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;
2018-10-02 03:02:47 +00:00
using osu.Framework.Input.Events;
2018-04-13 09:19:50 +00:00
using osu.Framework.Timing;
using osu.Game.Beatmaps;
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;
2018-11-20 07:51:59 +00:00
using osuTK;
using osuTK.Input;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Screens.Play
{
public class HUDOverlay : Container
{
private const int duration = 100;
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;
public readonly HoldForMenuButton HoldToQuit;
2018-04-13 09:19:50 +00:00
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
private Bindable<bool> showHud;
private readonly Container visibilityContainer;
2018-04-13 09:19:50 +00:00
private readonly BindableBool replayLoaded = new BindableBool();
private static bool hasShownNotificationOnce;
public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, WorkingBeatmap working, IClock offsetClock, IAdjustableClock adjustableClock)
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
2018-04-13 09:19:50 +00:00
{
visibilityContainer = new Container {
RelativeSizeAxes = Axes.Both,
AlwaysPresent = true, // The hud may be hidden but certain elements may need to still be updated
Children = new Drawable[] {
new Container {
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = 30,
AutoSizeAxes = Axes.Both,
2019-01-22 00:47:51 +00:00
AutoSizeDuration = 200,
AutoSizeEasing = Easing.Out,
Children = new Drawable[] {
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(),
},
},
HealthDisplay = CreateHealthDisplay(),
Progress = CreateProgress(),
ModDisplay = CreateModsContainer(),
}
},
2019-01-21 18:22:19 +00:00
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
new FillFlowContainer
2018-04-13 09:19:50 +00:00
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Position = -new Vector2(5, TwoLayerButton.SIZE_RETRACTED.Y),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
KeyCounter = CreateKeyCounter(adjustableClock as IFrameBasedClock),
HoldToQuit = CreateHoldForMenuButton(),
}
2018-04-13 09:19:50 +00:00
}
};
2018-04-13 09:19:50 +00:00
BindProcessor(scoreProcessor);
BindRulesetContainer(rulesetContainer);
Progress.Objects = rulesetContainer.Objects;
Progress.AudioClock = offsetClock;
2018-04-13 09:19:50 +00:00
Progress.AllowSeeking = rulesetContainer.HasReplayLoaded;
2018-07-28 10:22:52 +00:00
Progress.OnSeek = pos => adjustableClock.Seek(pos);
2018-04-13 09:19:50 +00:00
ModDisplay.Current.BindTo(working.Mods);
PlayerSettingsOverlay.PlaybackSettings.AdjustableClock = adjustableClock;
}
[BackgroundDependencyLoader(true)]
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
2018-04-13 09:19:50 +00:00
{
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
showHud.ValueChanged += hudVisibility => visibilityContainer.FadeTo(hudVisibility ? 1 : 0, duration);
2018-04-13 09:19:50 +00:00
showHud.TriggerChange();
if (!showHud && !hasShownNotificationOnce)
{
hasShownNotificationOnce = true;
notificationOverlay?.Post(new SimpleNotification
{
Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab."
});
}
}
protected override void LoadComplete()
{
base.LoadComplete();
replayLoaded.ValueChanged += replayLoadedValueChanged;
replayLoaded.TriggerChange();
}
private void replayLoadedValueChanged(bool loaded)
{
PlayerSettingsOverlay.ReplayLoaded = loaded;
if (loaded)
{
PlayerSettingsOverlay.Show();
ModDisplay.FadeIn(200);
2018-10-30 12:32:12 +00:00
KeyCounter.Margin = new MarginPadding(10) { Bottom = 30 };
2018-04-13 09:19:50 +00:00
}
else
{
PlayerSettingsOverlay.Hide();
ModDisplay.Delay(2000).FadeOut(200);
2018-10-30 12:32:12 +00:00
KeyCounter.Margin = new MarginPadding(10);
2018-04-13 09:19:50 +00:00
}
}
protected virtual void BindRulesetContainer(RulesetContainer rulesetContainer)
{
(rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter);
replayLoaded.BindTo(rulesetContainer.HasReplayLoaded);
Progress.BindRulestContainer(rulesetContainer);
}
2018-10-02 03:02:47 +00:00
protected override bool OnKeyDown(KeyDownEvent e)
2018-04-13 09:19:50 +00:00
{
2018-10-02 03:02:47 +00:00
if (e.Repeat) return false;
2018-04-13 09:19:50 +00:00
if (e.ShiftPressed)
2018-04-13 09:19:50 +00:00
{
2018-10-02 03:02:47 +00:00
switch (e.Key)
2018-04-13 09:19:50 +00:00
{
case Key.Tab:
showHud.Value = !showHud.Value;
return true;
}
}
2018-10-02 03:02:47 +00:00
return base.OnKeyDown(e);
2018-04-13 09:19:50 +00:00
}
protected virtual RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter
{
TextSize = 20,
BypassAutoSizeAxes = Axes.X,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopRight,
Margin = new MarginPadding { Top = 5, Right = 20 },
2018-04-13 09:19:50 +00:00
};
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
2018-04-13 09:19:50 +00:00
{
TextSize = 40,
2018-04-13 09:19:50 +00:00
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
};
protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
{
2018-04-13 09:19:50 +00:00
TextSize = 20,
BypassAutoSizeAxes = Axes.X,
Anchor = Anchor.TopRight,
Origin = Anchor.TopLeft,
Margin = new MarginPadding { Top = 5, Left = 20 },
2018-04-13 09:19:50 +00:00
};
protected virtual HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
{
Size = new Vector2(1, 5),
RelativeSizeAxes = Axes.X,
Margin = new MarginPadding { Top = 20 }
};
protected virtual KeyCounterCollection CreateKeyCounter(IFrameBasedClock offsetClock) => new KeyCounterCollection
2018-04-13 09:19:50 +00:00
{
FadeTime = 50,
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
AudioClock = offsetClock
2018-04-13 09:19:50 +00:00
};
protected virtual SongProgress CreateProgress() => new SongProgress
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.X,
};
protected virtual HoldForMenuButton CreateHoldForMenuButton() => new HoldForMenuButton
2018-04-21 15:24:31 +00:00
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
};
2018-04-13 09:19:50 +00:00
protected virtual ModDisplay CreateModsContainer() => new ModDisplay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 20, Right = 10 },
};
protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();
protected 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);
var shd = HealthDisplay as StandardHealthDisplay;
if (shd != null)
processor.NewJudgement += shd.Flash;
}
}
}