1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 11:28:00 +08:00

Move tick handling to DrawableSpinner itself

This commit is contained in:
Dean Herbert 2020-07-21 19:03:17 +09:00
parent 05102bc1ba
commit 947f4e0d4c
4 changed files with 86 additions and 94 deletions

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public readonly SpinnerDisc Disc;
public readonly SpinnerTicks Ticks;
public readonly SpinnerSpmCounter SpmCounter;
private readonly SpinnerBonusComponent bonusComponent;
private readonly SpinnerBonusDisplay bonusDisplay;
private readonly Container mainContainer;
@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Y = 120,
Alpha = 0
},
bonusComponent = new SpinnerBonusComponent(this, ticks)
bonusDisplay = new SpinnerBonusDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -199,6 +199,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (userTriggered || Time.Current < Spinner.EndTime)
return;
// Trigger a miss result for remaining ticks to avoid infinite gameplay.
foreach (var tick in ticks.Where(t => !t.IsHit))
tick.TriggerResult(HitResult.Miss);
ApplyResult(r =>
{
if (Progress >= 1)
@ -230,7 +234,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Ticks.Rotation = Disc.Rotation;
SpmCounter.SetRotation(Disc.CumulativeRotation);
bonusComponent.SetRotation(Disc.CumulativeRotation);
updateBonusScore();
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
float targetScale = relativeCircleScale + (1 - relativeCircleScale) * Progress;
@ -239,6 +244,37 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
symbol.Rotation = (float)Interpolation.Lerp(symbol.Rotation, Disc.Rotation / 2, Math.Clamp(Math.Abs(Time.Elapsed) / 40, 0, 1));
}
private int wholeSpins;
private void updateBonusScore()
{
if (ticks.Count == 0)
return;
int spins = (int)(Disc.CumulativeRotation / 360);
while (wholeSpins != spins)
{
if (wholeSpins < spins)
{
var tick = ticks.FirstOrDefault(t => !t.IsHit);
if (tick != null)
{
tick.TriggerResult(HitResult.Great);
if (tick is DrawableSpinnerBonusTick)
bonusDisplay.SetBonusCount(spins - Spinner.SpinsRequired);
}
wholeSpins++;
}
else
{
wholeSpins--;
}
}
}
protected override void UpdateInitialTransforms()
{
base.UpdateInitialTransforms();

View File

@ -17,11 +17,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
/// <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)
/// <param name="result">Whether to apply a <see cref="HitResult.Great"/> result, <see cref="HitResult.Miss"/> otherwise.</param>
internal void TriggerResult(HitResult result)
{
HitObject.StartTime = Time.Current;
ApplyResult(r => r.Type = hit ? HitResult.Great : HitResult.Miss);
ApplyResult(r => r.Type = result);
}
}
}

View File

@ -1,87 +0,0 @@
// 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 SetRotation(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.TriggerResult(true);
if (tick is DrawableSpinnerBonusTick)
{
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;
}
}
}

View File

@ -0,0 +1,44 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
/// <summary>
/// A component that tracks spinner spins and add bonus score for it.
/// </summary>
public class SpinnerBonusDisplay : CompositeDrawable
{
private readonly OsuSpriteText bonusCounter;
public SpinnerBonusDisplay()
{
AutoSizeAxes = Axes.Both;
InternalChild = bonusCounter = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Numeric.With(size: 24),
Alpha = 0,
};
}
private int displayedCount;
public void SetBonusCount(int count)
{
if (displayedCount == count)
return;
displayedCount = count;
bonusCounter.Text = $"{1000 * count}";
bonusCounter.FadeOutFromOne(1500);
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
}
}
}