1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 01:27:29 +08:00

Make taiko hitobject properly unproxy when rewound

This commit is contained in:
smoogipoo 2018-06-11 21:45:19 +09:00
parent f07e6370ca
commit 22dfe46572
4 changed files with 70 additions and 34 deletions

View File

@ -86,6 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
switch (State.Value)
{
case ArmedState.Idle:
UnproxyContent();
this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire();
break;
case ArmedState.Miss:
@ -93,6 +94,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
.Expire();
break;
case ArmedState.Hit:
if (X >= -0.05f)
ProxyContent();
var flash = circlePiece?.FlashBox;
if (flash != null)
{

View File

@ -20,12 +20,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableSwell : DrawableTaikoHitObject<Swell>
{
/// <summary>
/// Invoked when the swell has reached the hit target, i.e. when CurrentTime >= StartTime.
/// This is only ever invoked once.
/// </summary>
public event Action OnStart;
private const float target_ring_thick_border = 1.4f;
private const float target_ring_thin_border = 1f;
private const float target_ring_scale = 5f;
@ -40,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
/// </summary>
private int userHits;
private bool hasStarted;
private bool hasProxied;
private readonly SwellSymbolPiece symbol;
public DrawableSwell(Swell swell)
@ -48,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
FillMode = FillMode.Fit;
AddInternal(bodyContainer = new Container
Content.Add(bodyContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
@ -177,6 +171,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
switch (state)
{
case ArmedState.Idle:
hasProxied = false;
UnproxyContent();
break;
case ArmedState.Hit:
bodyContainer.Delay(untilJudgement).ScaleTo(1.4f, out_transition_time);
break;
@ -195,10 +193,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
X = Math.Max(0, X);
double t = Math.Min(HitObject.StartTime, Time.Current);
if (t == HitObject.StartTime && !hasStarted)
if (t == HitObject.StartTime && !hasProxied)
{
OnStart?.Invoke();
hasStarted = true;
ProxyContent();
hasProxied = true;
}
}

View File

@ -9,10 +9,62 @@ using OpenTK;
using System.Linq;
using osu.Game.Audio;
using System.Collections.Generic;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableHitObject<TaikoHitObject>, IKeyBindingHandler<TaikoAction>
public abstract class DrawableTaikoHitObject : DrawableHitObject<TaikoHitObject>, IKeyBindingHandler<TaikoAction>
{
protected readonly Container Content;
public readonly Container ProxiedContent;
private readonly Container nonProxiedContent;
protected DrawableTaikoHitObject(TaikoHitObject hitObject)
: base(hitObject)
{
InternalChildren = new[]
{
nonProxiedContent = new Container
{
RelativeSizeAxes = Axes.Both,
Child = Content = new Container { RelativeSizeAxes = Axes.Both }
},
ProxiedContent = new Container { RelativeSizeAxes = Axes.Both }
};
}
/// <summary>
/// <see cref="ProxiedContent"/> is proxied into an upper layer. We don't want to get masked away otherwise <see cref="ProxiedContent"/> would too.
/// </summary>
protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false;
/// <summary>
/// Moves <see cref="Content"/> to a layer proxied above the playfield.
/// </summary>
protected void ProxyContent()
{
nonProxiedContent.Remove(Content);
ProxiedContent.Remove(Content);
ProxiedContent.Add(Content);
}
/// <summary>
/// Moves <see cref="Content"/> to the normal hitobject layer.
/// </summary>
protected void UnproxyContent()
{
ProxiedContent.Remove(Content);
nonProxiedContent.Remove(Content);
nonProxiedContent.Add(Content);
}
public abstract bool OnPressed(TaikoAction action);
public virtual bool OnReleased(TaikoAction action) => false;
}
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableTaikoHitObject
where TaikoHitType : TaikoHitObject
{
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
@ -34,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Both;
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
InternalChild = MainPiece = CreateMainPiece();
Content.Add(MainPiece = CreateMainPiece());
MainPiece.KiaiMode = HitObject.Kiai;
}
@ -44,9 +96,5 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected override string SampleNamespace => "Taiko";
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
public abstract bool OnPressed(TaikoAction action);
public virtual bool OnReleased(TaikoAction action) => false;
}
}

View File

@ -216,10 +216,9 @@ namespace osu.Game.Rulesets.Taiko.UI
if (barline != null)
barlineContainer.Add(barline.CreateProxy());
// Swells should be moved at the very top of the playfield when they reach the hit target
var swell = h as DrawableSwell;
if (swell != null)
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
var taikoObject = h as DrawableTaikoHitObject;
if (taikoObject != null)
topLevelHitContainer.Add(taikoObject.ProxiedContent.CreateProxy());
}
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
@ -244,19 +243,6 @@ namespace osu.Game.Rulesets.Taiko.UI
hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == judgedObject)?.VisualiseSecondHit();
else
{
if (judgedObject.X >= -0.05f && judgedObject is DrawableHit)
{
// If we're far enough away from the left stage, we should bring outselves in front of it
// Todo: The following try-catch is temporary for replay rewinding support
try
{
topLevelHitContainer.Add(judgedObject.CreateProxy());
}
catch
{
}
}
hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim));
if (judgedObject.HitObject.Kiai)