mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 03:25:11 +08:00
Move spinner bonus scoring to it's own component class
Also fixes counter rewinding issue and does optimizations.
This commit is contained in:
parent
419656cea4
commit
949ab4e0d3
@ -26,11 +26,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
protected readonly Spinner Spinner;
|
||||
|
||||
private readonly Container<DrawableSpinnerTick> ticks;
|
||||
private readonly OsuSpriteText bonusCounter;
|
||||
|
||||
public readonly SpinnerDisc Disc;
|
||||
public readonly SpinnerTicks Ticks;
|
||||
public readonly SpinnerSpmCounter SpmCounter;
|
||||
private readonly SpinnerBonusComponent bonusComponent;
|
||||
|
||||
private readonly Container mainContainer;
|
||||
|
||||
@ -123,13 +123,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Y = 120,
|
||||
Alpha = 0
|
||||
},
|
||||
bonusCounter = new OsuSpriteText
|
||||
bonusComponent = new SpinnerBonusComponent(this, ticks)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Y = -120,
|
||||
Font = OsuFont.Numeric.With(size: 24),
|
||||
Alpha = 0,
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -226,8 +224,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
base.Update();
|
||||
}
|
||||
|
||||
private int currentSpins;
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
@ -235,30 +231,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
circle.Rotation = Disc.Rotation;
|
||||
Ticks.Rotation = Disc.Rotation;
|
||||
SpmCounter.SetRotation(Disc.RotationAbsolute);
|
||||
|
||||
var newSpins = (int)(Disc.RotationAbsolute / 360) - currentSpins;
|
||||
|
||||
for (int i = currentSpins; i < currentSpins + newSpins; i++)
|
||||
{
|
||||
if (i < 0 || i >= ticks.Count)
|
||||
break;
|
||||
|
||||
var tick = ticks[i];
|
||||
|
||||
tick.HasBonusPoints = Progress >= 1 && i > Spinner.SpinsRequired;
|
||||
|
||||
if (tick.HasBonusPoints)
|
||||
{
|
||||
bonusCounter.Text = $"{(i - Spinner.SpinsRequired) * 1000}";
|
||||
bonusCounter
|
||||
.FadeOutFromOne(1500)
|
||||
.ScaleTo(1.5f).ScaleTo(1f, 1000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
tick.TriggerResult(HitResult.Great);
|
||||
}
|
||||
|
||||
currentSpins += newSpins;
|
||||
bonusComponent.UpdateRotation(Disc.RotationAbsolute);
|
||||
|
||||
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
||||
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
|
||||
@ -299,15 +272,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
sequence.ScaleTo(Scale * 0.8f, 320, Easing.In);
|
||||
break;
|
||||
}
|
||||
|
||||
if (state != ArmedState.Idle)
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
foreach (var tick in ticks.Where(t => !t.IsHit))
|
||||
tick.TriggerResult(HitResult.Miss);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
/// <summary>
|
||||
/// Whether this judgement has a bonus of 1,000 points additional to the numeric result.
|
||||
/// Should be set when a spin occured after the spinner has completed.
|
||||
/// Set when a spin occured after the spinner has completed.
|
||||
/// </summary>
|
||||
public bool HasBonusPoints
|
||||
{
|
||||
@ -44,10 +44,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Samples.AddAdjustment(AdjustableProperty.Volume, bonusSampleVolume);
|
||||
}
|
||||
|
||||
public void TriggerResult(HitResult result)
|
||||
/// <summary>
|
||||
/// Apply a judgement result.
|
||||
/// </summary>
|
||||
/// <param name="hit">Whether to apply a <see cref="HitResult.Great"/> result, <see cref="HitResult.Miss"/> otherwise.</param>
|
||||
internal void TriggerResult(bool hit)
|
||||
{
|
||||
HitObject.StartTime = Time.Current;
|
||||
ApplyResult(r => r.Type = result);
|
||||
ApplyResult(r => r.Type = hit ? HitResult.Great : HitResult.Miss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
/// <summary>
|
||||
/// A component that tracks spinner spins and add bonus score for it.
|
||||
/// </summary>
|
||||
public class SpinnerBonusComponent : CompositeDrawable
|
||||
{
|
||||
private readonly DrawableSpinner drawableSpinner;
|
||||
private readonly Container<DrawableSpinnerTick> ticks;
|
||||
private readonly OsuSpriteText bonusCounter;
|
||||
|
||||
public SpinnerBonusComponent(DrawableSpinner drawableSpinner, Container<DrawableSpinnerTick> ticks)
|
||||
{
|
||||
this.drawableSpinner = drawableSpinner;
|
||||
this.ticks = ticks;
|
||||
|
||||
drawableSpinner.OnNewResult += onNewResult;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = bonusCounter = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.Numeric.With(size: 24),
|
||||
Alpha = 0,
|
||||
};
|
||||
}
|
||||
|
||||
private int currentSpins;
|
||||
|
||||
public void UpdateRotation(double rotation)
|
||||
{
|
||||
if (ticks.Count == 0)
|
||||
return;
|
||||
|
||||
int spinsRequired = ((Spinner)drawableSpinner.HitObject).SpinsRequired;
|
||||
|
||||
int newSpins = Math.Clamp((int)(rotation / 360), 0, ticks.Count - 1);
|
||||
int direction = Math.Sign(newSpins - currentSpins);
|
||||
|
||||
while (currentSpins != newSpins)
|
||||
{
|
||||
var tick = ticks[currentSpins];
|
||||
|
||||
if (direction >= 0)
|
||||
{
|
||||
tick.HasBonusPoints = currentSpins > spinsRequired;
|
||||
tick.TriggerResult(true);
|
||||
}
|
||||
|
||||
if (tick.HasBonusPoints)
|
||||
{
|
||||
bonusCounter.Text = $"{1000 * (currentSpins - spinsRequired)}";
|
||||
bonusCounter.FadeOutFromOne(1500);
|
||||
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
currentSpins += direction;
|
||||
}
|
||||
}
|
||||
|
||||
private void onNewResult(DrawableHitObject hitObject, JudgementResult result)
|
||||
{
|
||||
if (!result.HasResult || hitObject != drawableSpinner)
|
||||
return;
|
||||
|
||||
// Trigger a miss result for remaining ticks to avoid infinite gameplay.
|
||||
foreach (var tick in ticks.Where(t => !t.IsHit))
|
||||
tick.TriggerResult(false);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
drawableSpinner.OnNewResult -= onNewResult;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user