mirror of
https://github.com/ppy/osu
synced 2024-12-25 16:22:23 +00:00
Fix fruit positions getting mangled when exploded
This commit is contained in:
parent
93c1a27f22
commit
fbfe3a4887
@ -21,11 +21,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
public Bindable<Color4> AccentColour { get; } = new Bindable<Color4>();
|
||||
public Bindable<bool> HyperDash { get; } = new Bindable<bool>();
|
||||
public Bindable<int> IndexInBeatmap { get; } = new Bindable<int>();
|
||||
|
||||
public Vector2 DisplayPosition => DrawPosition;
|
||||
public Vector2 DisplaySize => Size * Scale;
|
||||
|
||||
public float DisplayRotation => Rotation;
|
||||
|
||||
public double DisplayStartTime => HitObject.StartTime;
|
||||
|
||||
/// <summary>
|
||||
@ -44,19 +42,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the hit object visual state from another <see cref="IHasCatchObjectState"/> object.
|
||||
/// </summary>
|
||||
public virtual void CopyStateFrom(IHasCatchObjectState objectState)
|
||||
{
|
||||
HitObject = objectState.HitObject;
|
||||
Scale = Vector2.Divide(objectState.DisplaySize, Size);
|
||||
Rotation = objectState.DisplayRotation;
|
||||
AccentColour.Value = objectState.AccentColour.Value;
|
||||
HyperDash.Value = objectState.HyperDash.Value;
|
||||
IndexInBeatmap.Value = objectState.IndexInBeatmap.Value;
|
||||
}
|
||||
|
||||
protected override void FreeAfterUse()
|
||||
{
|
||||
ClearTransforms();
|
||||
@ -64,5 +49,16 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
|
||||
base.FreeAfterUse();
|
||||
}
|
||||
|
||||
public void RestoreState(CatchObjectState state)
|
||||
{
|
||||
HitObject = state.HitObject;
|
||||
AccentColour.Value = state.AccentColour;
|
||||
HyperDash.Value = state.HyperDash;
|
||||
IndexInBeatmap.Value = state.IndexInBeatmap;
|
||||
Position = state.DisplayPosition;
|
||||
Scale = Vector2.Divide(state.DisplaySize, Size);
|
||||
Rotation = state.DisplayRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
/// </summary>
|
||||
protected readonly Container ScalingContainer;
|
||||
|
||||
public Vector2 DisplayPosition => DrawPosition;
|
||||
|
||||
public Vector2 DisplaySize => ScalingContainer.Size * ScalingContainer.Scale;
|
||||
|
||||
public float DisplayRotation => ScalingContainer.Rotation;
|
||||
@ -95,5 +97,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
|
||||
base.OnFree();
|
||||
}
|
||||
|
||||
public void RestoreState(CatchObjectState state) => throw new NotSupportedException("Cannot restore state into a drawable catch hitobject.");
|
||||
}
|
||||
}
|
||||
|
@ -13,17 +13,37 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
|
||||
public interface IHasCatchObjectState
|
||||
{
|
||||
PalpableCatchHitObject HitObject { get; }
|
||||
|
||||
double DisplayStartTime { get; }
|
||||
|
||||
Bindable<Color4> AccentColour { get; }
|
||||
|
||||
Bindable<bool> HyperDash { get; }
|
||||
|
||||
Bindable<int> IndexInBeatmap { get; }
|
||||
|
||||
double DisplayStartTime { get; }
|
||||
Vector2 DisplayPosition { get; }
|
||||
Vector2 DisplaySize { get; }
|
||||
|
||||
float DisplayRotation { get; }
|
||||
|
||||
void RestoreState(CatchObjectState state);
|
||||
}
|
||||
|
||||
public static class HasCatchObjectStateExtensions
|
||||
{
|
||||
public static CatchObjectState SaveState(this IHasCatchObjectState target) => new CatchObjectState(
|
||||
target.HitObject,
|
||||
target.AccentColour.Value,
|
||||
target.HyperDash.Value,
|
||||
target.IndexInBeatmap.Value,
|
||||
target.DisplayStartTime,
|
||||
target.DisplayPosition,
|
||||
target.DisplaySize,
|
||||
target.DisplayRotation);
|
||||
}
|
||||
|
||||
public readonly record struct CatchObjectState(
|
||||
PalpableCatchHitObject HitObject,
|
||||
Color4 AccentColour,
|
||||
bool HyperDash,
|
||||
int IndexInBeatmap,
|
||||
double DisplayStartTime,
|
||||
Vector2 DisplayPosition,
|
||||
Vector2 DisplaySize,
|
||||
float DisplayRotation);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -362,7 +363,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (caughtObject == null) return;
|
||||
|
||||
caughtObject.CopyStateFrom(drawableObject);
|
||||
caughtObject.RestoreState(drawableObject.SaveState());
|
||||
caughtObject.Anchor = Anchor.TopCentre;
|
||||
caughtObject.Position = position;
|
||||
caughtObject.Scale *= caught_fruit_scale_adjust;
|
||||
@ -411,41 +412,50 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
}
|
||||
}
|
||||
|
||||
private CaughtObject getDroppedObject(CaughtObject caughtObject)
|
||||
private CaughtObject getDroppedObject(CatchObjectState state)
|
||||
{
|
||||
var droppedObject = getCaughtObject(caughtObject.HitObject);
|
||||
var droppedObject = getCaughtObject(state.HitObject);
|
||||
Debug.Assert(droppedObject != null);
|
||||
|
||||
droppedObject.CopyStateFrom(caughtObject);
|
||||
droppedObject.RestoreState(state);
|
||||
droppedObject.Anchor = Anchor.TopLeft;
|
||||
droppedObject.Position = caughtObjectContainer.ToSpaceOfOtherDrawable(caughtObject.DrawPosition, droppedObjectTarget);
|
||||
droppedObject.Position = caughtObjectContainer.ToSpaceOfOtherDrawable(state.DisplayPosition, droppedObjectTarget);
|
||||
|
||||
return droppedObject;
|
||||
}
|
||||
|
||||
private void clearPlate(DroppedObjectAnimation animation)
|
||||
{
|
||||
var caughtObjects = caughtObjectContainer.Children.ToArray();
|
||||
int caughtCount = caughtObjectContainer.Children.Count;
|
||||
CatchObjectState[] states = ArrayPool<CatchObjectState>.Shared.Rent(caughtCount);
|
||||
|
||||
caughtObjectContainer.Clear(false);
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < caughtCount; i++)
|
||||
states[i] = caughtObjectContainer.Children[i].SaveState();
|
||||
|
||||
// Use the already returned PoolableDrawables for new objects
|
||||
var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray();
|
||||
caughtObjectContainer.Clear(false);
|
||||
|
||||
droppedObjectTarget.AddRange(droppedObjects);
|
||||
|
||||
foreach (var droppedObject in droppedObjects)
|
||||
applyDropAnimation(droppedObject, animation);
|
||||
for (int i = 0; i < caughtCount; i++)
|
||||
{
|
||||
CaughtObject obj = getDroppedObject(states[i]);
|
||||
droppedObjectTarget.Add(obj);
|
||||
applyDropAnimation(obj, animation);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<CatchObjectState>.Shared.Return(states);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeFromPlate(CaughtObject caughtObject, DroppedObjectAnimation animation)
|
||||
{
|
||||
CatchObjectState state = caughtObject.SaveState();
|
||||
caughtObjectContainer.Remove(caughtObject, false);
|
||||
|
||||
var droppedObject = getDroppedObject(caughtObject);
|
||||
|
||||
var droppedObject = getDroppedObject(state);
|
||||
droppedObjectTarget.Add(droppedObject);
|
||||
|
||||
applyDropAnimation(droppedObject, animation);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user