mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 08:12:56 +08:00
Move tick handling to DrawableSpinner itself
This commit is contained in:
parent
05102bc1ba
commit
947f4e0d4c
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public readonly SpinnerDisc Disc;
|
public readonly SpinnerDisc Disc;
|
||||||
public readonly SpinnerTicks Ticks;
|
public readonly SpinnerTicks Ticks;
|
||||||
public readonly SpinnerSpmCounter SpmCounter;
|
public readonly SpinnerSpmCounter SpmCounter;
|
||||||
private readonly SpinnerBonusComponent bonusComponent;
|
private readonly SpinnerBonusDisplay bonusDisplay;
|
||||||
|
|
||||||
private readonly Container mainContainer;
|
private readonly Container mainContainer;
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Y = 120,
|
Y = 120,
|
||||||
Alpha = 0
|
Alpha = 0
|
||||||
},
|
},
|
||||||
bonusComponent = new SpinnerBonusComponent(this, ticks)
|
bonusDisplay = new SpinnerBonusDisplay
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -199,6 +199,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (userTriggered || Time.Current < Spinner.EndTime)
|
if (userTriggered || Time.Current < Spinner.EndTime)
|
||||||
return;
|
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 =>
|
ApplyResult(r =>
|
||||||
{
|
{
|
||||||
if (Progress >= 1)
|
if (Progress >= 1)
|
||||||
@ -230,7 +234,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Ticks.Rotation = Disc.Rotation;
|
Ticks.Rotation = Disc.Rotation;
|
||||||
|
|
||||||
SpmCounter.SetRotation(Disc.CumulativeRotation);
|
SpmCounter.SetRotation(Disc.CumulativeRotation);
|
||||||
bonusComponent.SetRotation(Disc.CumulativeRotation);
|
|
||||||
|
updateBonusScore();
|
||||||
|
|
||||||
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
||||||
float targetScale = relativeCircleScale + (1 - relativeCircleScale) * Progress;
|
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));
|
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()
|
protected override void UpdateInitialTransforms()
|
||||||
{
|
{
|
||||||
base.UpdateInitialTransforms();
|
base.UpdateInitialTransforms();
|
||||||
|
@ -17,11 +17,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply a judgement result.
|
/// Apply a judgement result.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hit">Whether to apply a <see cref="HitResult.Great"/> result, <see cref="HitResult.Miss"/> otherwise.</param>
|
/// <param name="result">Whether to apply a <see cref="HitResult.Great"/> result, <see cref="HitResult.Miss"/> otherwise.</param>
|
||||||
internal void TriggerResult(bool hit)
|
internal void TriggerResult(HitResult result)
|
||||||
{
|
{
|
||||||
HitObject.StartTime = Time.Current;
|
ApplyResult(r => r.Type = result);
|
||||||
ApplyResult(r => r.Type = hit ? HitResult.Great : HitResult.Miss);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user