mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 14:23:02 +08:00
commit
6e3125e115
@ -138,8 +138,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
if (h is Spinner)
|
||||
{
|
||||
targetPosition.X = Frames[Frames.Count - 1].MouseX;
|
||||
targetPosition.Y = Frames[Frames.Count - 1].MouseY;
|
||||
targetPosition = Frames[Frames.Count - 1].Position;
|
||||
|
||||
Vector2 difference = spinner_centre - targetPosition;
|
||||
|
||||
@ -193,7 +192,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
addFrameToReplay(lastFrame);
|
||||
}
|
||||
|
||||
Vector2 lastPosition = new Vector2(lastFrame.MouseX, lastFrame.MouseY);
|
||||
Vector2 lastPosition = lastFrame.Position;
|
||||
|
||||
double timeDifference = applyModsToTime(h.StartTime - lastFrame.Time);
|
||||
|
||||
|
@ -98,11 +98,11 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
||||
double osuDuration = distance / osuVelocity;
|
||||
|
||||
// If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat
|
||||
double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats) / 8;
|
||||
double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats);
|
||||
|
||||
if (tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength)
|
||||
{
|
||||
for (double j = obj.StartTime; j <= distanceData.EndTime + tickSpacing; j += tickSpacing)
|
||||
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
|
||||
{
|
||||
// Todo: This should generate different type of hits (including strongs)
|
||||
// depending on hitobject sound additions (not implemented fully yet)
|
||||
|
@ -27,11 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
{
|
||||
if (!userTriggered)
|
||||
{
|
||||
if (Judgement.TimeOffset > HitObject.HitWindow)
|
||||
Judgement.Result = HitResult.Miss;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||
/// <summary>
|
||||
/// The size of a tick.
|
||||
/// </summary>
|
||||
private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 4;
|
||||
private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 6;
|
||||
|
||||
private bool filled;
|
||||
public bool Filled
|
||||
|
@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
bool hitButton = true;
|
||||
|
||||
Frames.Add(new ReplayFrame(-100000, 320, 240, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 320, 240, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
|
||||
|
||||
for (int i = 0; i < beatmap.HitObjects.Count; i++)
|
||||
{
|
||||
@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
break;
|
||||
}
|
||||
|
||||
Frames.Add(new ReplayFrame(j, 0, 0, button));
|
||||
Frames.Add(new ReplayFrame(j, null, null, button));
|
||||
d = (d + 1) % 4;
|
||||
if (++count > req)
|
||||
break;
|
||||
@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
foreach (var tick in drumRoll.Ticks)
|
||||
{
|
||||
Frames.Add(new ReplayFrame(tick.StartTime, 0, 0, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
|
||||
Frames.Add(new ReplayFrame(tick.StartTime, null, null, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
|
||||
hitButton = !hitButton;
|
||||
}
|
||||
}
|
||||
@ -95,18 +95,18 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
|
||||
}
|
||||
|
||||
Frames.Add(new ReplayFrame(h.StartTime, 0, 0, button));
|
||||
Frames.Add(new ReplayFrame(h.StartTime, null, null, button));
|
||||
}
|
||||
else
|
||||
throw new Exception("Unknown hit object type.");
|
||||
|
||||
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, 0, 0, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
|
||||
|
||||
if (i < beatmap.HitObjects.Count - 1)
|
||||
{
|
||||
double waitTime = beatmap.HitObjects[i + 1].StartTime - 1000;
|
||||
if (waitTime > endTime)
|
||||
Frames.Add(new ReplayFrame(waitTime, 0, 0, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
|
||||
}
|
||||
|
||||
hitButton = !hitButton;
|
||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Database
|
||||
|
||||
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
|
||||
using (var reader = new StreamReader(lzma))
|
||||
score.Replay = createReplay(reader);
|
||||
score.Replay = createLegacyReplay(reader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,11 +116,11 @@ namespace osu.Game.Database
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a replay which is read from a stream.
|
||||
/// Creates a legacy replay which is read from a stream.
|
||||
/// </summary>
|
||||
/// <param name="reader">The stream reader.</param>
|
||||
/// <returns>The replay.</returns>
|
||||
private Replay createReplay(StreamReader reader)
|
||||
/// <returns>The legacy replay.</returns>
|
||||
private Replay createLegacyReplay(StreamReader reader)
|
||||
{
|
||||
var frames = new List<ReplayFrame>();
|
||||
|
||||
|
@ -80,6 +80,10 @@ namespace osu.Game.Graphics
|
||||
public Color4 GrayE = FromHex(@"eee");
|
||||
public Color4 GrayF = FromHex(@"fff");
|
||||
|
||||
public Color4 Red = FromHex(@"fc4549");
|
||||
public Color4 RedLighter = FromHex(@"ffeded");
|
||||
public Color4 RedLight = FromHex(@"ed7787");
|
||||
public Color4 Red = FromHex(@"ed1121");
|
||||
public Color4 RedDark = FromHex(@"ba0011");
|
||||
public Color4 RedDarker = FromHex(@"870000");
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ namespace osu.Game.Rulesets.Replays
|
||||
{
|
||||
public class ReplayFrame
|
||||
{
|
||||
public Vector2 Position => new Vector2(MouseX, MouseY);
|
||||
public Vector2 Position => new Vector2(MouseX ?? 0, MouseY ?? 0);
|
||||
|
||||
public bool IsImportant => MouseLeft || MouseRight;
|
||||
public bool IsImportant => MouseX.HasValue && MouseY.HasValue && (MouseLeft || MouseRight);
|
||||
|
||||
public float MouseX;
|
||||
public float MouseY;
|
||||
public float? MouseX;
|
||||
public float? MouseY;
|
||||
|
||||
public bool MouseLeft => MouseLeft1 || MouseLeft2;
|
||||
public bool MouseRight => MouseRight1 || MouseRight2;
|
||||
@ -55,10 +55,10 @@ namespace osu.Game.Rulesets.Replays
|
||||
|
||||
}
|
||||
|
||||
public ReplayFrame(double time, float posX, float posY, ReplayButtonState buttonState)
|
||||
public ReplayFrame(double time, float? mouseX, float? mouseY, ReplayButtonState buttonState)
|
||||
{
|
||||
MouseX = posX;
|
||||
MouseY = posY;
|
||||
MouseX = mouseX;
|
||||
MouseY = mouseY;
|
||||
ButtonState = buttonState;
|
||||
Time = time;
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
public event Action Failed;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a new judgement has occurred. This occurs after the judgement has been processed by the <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
public event Action<Judgement> NewJudgement;
|
||||
|
||||
/// <summary>
|
||||
/// The current total score.
|
||||
/// </summary>
|
||||
@ -105,6 +110,15 @@ namespace osu.Game.Rulesets.Scoring
|
||||
Failed?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies subscribers of <see cref="NewJudgement"/> that a new judgement has occurred.
|
||||
/// </summary>
|
||||
/// <param name="judgement">The judgement to notify subscribers of.</param>
|
||||
protected void NotifyNewJudgement(Judgement judgement)
|
||||
{
|
||||
NewJudgement?.Invoke(judgement);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a score populated with data for the current play this processor is responsible for.
|
||||
/// </summary>
|
||||
@ -177,6 +191,8 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
Judgements.Add(judgement);
|
||||
OnNewJudgement(judgement);
|
||||
|
||||
NotifyNewJudgement(judgement);
|
||||
}
|
||||
else
|
||||
OnJudgementChanged(judgement);
|
||||
|
@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.UI
|
||||
}
|
||||
}
|
||||
|
||||
public void BindProcessor(ScoreProcessor processor)
|
||||
public virtual void BindProcessor(ScoreProcessor processor)
|
||||
{
|
||||
ScoreCounter?.Current.BindTo(processor.TotalScore);
|
||||
AccuracyCounter?.Current.BindTo(processor.Accuracy);
|
||||
@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.UI
|
||||
HealthDisplay?.Current.BindTo(processor.Health);
|
||||
}
|
||||
|
||||
public void BindHitRenderer(HitRenderer hitRenderer)
|
||||
public virtual void BindHitRenderer(HitRenderer hitRenderer)
|
||||
{
|
||||
hitRenderer.InputManager.Add(KeyCounter.GetReceptor());
|
||||
}
|
||||
|
@ -3,15 +3,42 @@
|
||||
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
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 System;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
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
|
||||
@ -32,9 +59,10 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
fill.EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Colour = glowColour,
|
||||
Colour = glowColour.Opacity(base_glow_opacity),
|
||||
Radius = 8,
|
||||
Type = EdgeEffectType.Glow
|
||||
Roundness = 4,
|
||||
Type = EdgeEffectType.Glow,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -51,7 +79,7 @@ namespace osu.Game.Rulesets.UI
|
||||
fill = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0, 1),
|
||||
Size = new Vector2(0, 1),
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
@ -64,6 +92,16 @@ namespace osu.Game.Rulesets.UI
|
||||
};
|
||||
}
|
||||
|
||||
protected override void SetHealth(float value) => fill.ScaleTo(new Vector2(value, 1), 200, EasingTypes.OutQuint);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,11 @@
|
||||
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
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;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
@ -75,8 +75,17 @@ namespace osu.Game.Rulesets.UI
|
||||
if (shd != null)
|
||||
{
|
||||
shd.AccentColour = colours.BlueLighter;
|
||||
shd.GlowColour = colours.BlueDarker.Opacity(0.6f);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user