1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-08 08:37:40 +08:00
osu-lazer/osu.Game/Screens/Play/HUDOverlay.cs

250 lines
8.8 KiB
C#
Raw Normal View History

// 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.
2018-04-13 17:19:50 +08:00
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2018-10-02 11:02:47 +08:00
using osu.Framework.Input.Events;
2018-04-13 17:19:50 +08: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 15:51:59 +08:00
using osuTK;
using osuTK.Input;
2018-04-13 17:19:50 +08: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 17:19:50 +08:00
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
private Bindable<bool> showHud;
private readonly Container visibilityContainer;
2018-04-13 17:19:50 +08: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 17:19:50 +08:00
{
2019-01-23 13:51:13 +08:00
visibilityContainer = new Container
{
RelativeSizeAxes = Axes.Both,
2019-01-23 13:51:13 +08:00
Children = new Drawable[]
{
new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = 30,
AutoSizeAxes = Axes.Both,
2019-01-22 08:47:51 +08:00
AutoSizeDuration = 200,
AutoSizeEasing = Easing.Out,
2019-01-23 13:51:13 +08:00
Children = new Drawable[]
{
AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(),
},
},
HealthDisplay = CreateHealthDisplay(),
Progress = CreateProgress(),
ModDisplay = CreateModsContainer(),
}
},
2019-01-22 02:22:19 +08:00
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
new FillFlowContainer
2018-04-13 17:19:50 +08: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 17:19:50 +08:00
}
};
2018-04-13 17:19:50 +08:00
BindProcessor(scoreProcessor);
BindRulesetContainer(rulesetContainer);
Progress.Objects = rulesetContainer.Objects;
Progress.AudioClock = offsetClock;
2018-04-13 17:19:50 +08:00
Progress.AllowSeeking = rulesetContainer.HasReplayLoaded;
2018-07-28 18:22:52 +08:00
Progress.OnSeek = pos => adjustableClock.Seek(pos);
2018-04-13 17:19:50 +08:00
ModDisplay.Current.BindTo(working.Mods);
PlayerSettingsOverlay.PlaybackSettings.AdjustableClock = adjustableClock;
}
[BackgroundDependencyLoader(true)]
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
2018-04-13 17:19:50 +08:00
{
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
showHud.ValueChanged += hudVisibility => visibilityContainer.FadeTo(hudVisibility ? 1 : 0, duration);
2018-04-13 17:19:50 +08: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 20:32:12 +08:00
KeyCounter.Margin = new MarginPadding(10) { Bottom = 30 };
2018-04-13 17:19:50 +08:00
}
else
{
PlayerSettingsOverlay.Hide();
ModDisplay.Delay(2000).FadeOut(200);
2018-10-30 20:32:12 +08:00
KeyCounter.Margin = new MarginPadding(10);
2018-04-13 17:19:50 +08:00
}
}
protected virtual void BindRulesetContainer(RulesetContainer rulesetContainer)
{
(rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter);
replayLoaded.BindTo(rulesetContainer.HasReplayLoaded);
Progress.BindRulestContainer(rulesetContainer);
}
2018-10-02 11:02:47 +08:00
protected override bool OnKeyDown(KeyDownEvent e)
2018-04-13 17:19:50 +08:00
{
2018-10-02 11:02:47 +08:00
if (e.Repeat) return false;
2018-04-13 17:19:50 +08:00
if (e.ShiftPressed)
2018-04-13 17:19:50 +08:00
{
2018-10-02 11:02:47 +08:00
switch (e.Key)
2018-04-13 17:19:50 +08:00
{
case Key.Tab:
showHud.Value = !showHud.Value;
return true;
}
}
2018-10-02 11:02:47 +08:00
return base.OnKeyDown(e);
2018-04-13 17:19:50 +08: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 17:19:50 +08:00
};
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
2018-04-13 17:19:50 +08:00
{
TextSize = 40,
2018-04-13 17:19:50 +08:00
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
};
protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
{
2018-04-13 17:19:50 +08:00
TextSize = 20,
BypassAutoSizeAxes = Axes.X,
Anchor = Anchor.TopRight,
Origin = Anchor.TopLeft,
Margin = new MarginPadding { Top = 5, Left = 20 },
2018-04-13 17:19:50 +08: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 17:19:50 +08:00
{
FadeTime = 50,
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
AudioClock = offsetClock
2018-04-13 17:19:50 +08: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 23:24:31 +08:00
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
};
2018-04-13 17:19:50 +08: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;
}
}
}