Skip to content

Commit

Permalink
add hitobject easing
Browse files Browse the repository at this point in the history
  • Loading branch information
flustix committed Sep 19, 2024
1 parent 7add192 commit 7c67c94
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 5 deletions.
1 change: 1 addition & 0 deletions fluXis.Game/Graphics/UserInterface/Color/FluXisColors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static class FluXisColors
public static Colour4 PlayfieldRotate => Colour4.FromHex("#8AF7A2");
public static Colour4 PlayfieldFade => Colour4.FromHex("#0180FE");
public static Colour4 HitObjectFade => Colour4.FromHex("#8AF3F7");
public static Colour4 HitObjectEase => Colour4.FromHex("#5B92FF");
public static Colour4 BeatPulse => Colour4.FromHex("#FF6666");
public static Colour4 Note => Colour4.FromHex("#FFFFFF");
public static Colour4 Shader => Colour4.FromHex("#D65C5C");
Expand Down
6 changes: 6 additions & 0 deletions fluXis.Game/Map/MapEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class MapEvents : IDeepCloneable<MapEvents>
[JsonProperty("hitfade")]
public List<HitObjectFadeEvent> HitObjectFadeEvents { get; private set; } = new();

[JsonProperty("hitease")]
public List<HitObjectEaseEvent> HitObjectEaseEvents { get; private set; } = new();

[JsonProperty("shake")]
public List<ShakeEvent> ShakeEvents { get; private set; } = new();

Expand All @@ -57,6 +60,7 @@ public class MapEvents : IDeepCloneable<MapEvents>
&& PlayfieldRotateEvents.Count == 0
&& PlayfieldFadeEvents.Count == 0
&& HitObjectFadeEvents.Count == 0
&& HitObjectEaseEvents.Count == 0
&& ShakeEvents.Count == 0
&& ShaderEvents.Count == 0
&& BeatPulseEvents.Count == 0
Expand Down Expand Up @@ -222,6 +226,7 @@ public MapEvents Sort()
PlayfieldScaleEvents.Sort(compare);
PlayfieldFadeEvents.Sort(compare);
HitObjectFadeEvents.Sort(compare);
HitObjectEaseEvents.Sort(compare);
ShakeEvents.Sort(compare);
ShaderEvents.Sort(compare);
BeatPulseEvents.Sort(compare);
Expand Down Expand Up @@ -252,6 +257,7 @@ public MapEvents DeepClone()
clone.PlayfieldRotateEvents = new List<PlayfieldRotateEvent>(PlayfieldRotateEvents);
clone.PlayfieldFadeEvents = new List<PlayfieldFadeEvent>(PlayfieldFadeEvents);
clone.HitObjectFadeEvents = new List<HitObjectFadeEvent>(HitObjectFadeEvents);
clone.HitObjectEaseEvents = new List<HitObjectEaseEvent>(HitObjectEaseEvents);
clone.ShakeEvents = new List<ShakeEvent>(ShakeEvents);
clone.ShaderEvents = new List<ShaderEvent>(ShaderEvents);
clone.BeatPulseEvents = new List<BeatPulseEvent>(BeatPulseEvents);
Expand Down
14 changes: 14 additions & 0 deletions fluXis.Game/Map/Structures/Events/HitObjectEaseEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using fluXis.Game.Map.Structures.Bases;
using Newtonsoft.Json;
using osu.Framework.Graphics;

namespace fluXis.Game.Map.Structures.Events;

public class HitObjectEaseEvent : IMapEvent, IHasEasing
{
[JsonProperty("time")]
public double Time { get; set; }

[JsonProperty("ease")]
public Easing Easing { get; set; }
}
24 changes: 24 additions & 0 deletions fluXis.Game/Screens/Edit/EditorMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public class EditorMap
public event Action<HitObjectFadeEvent> HitObjectFadeEventRemoved;
public event Action<HitObjectFadeEvent> HitObjectFadeEventUpdated;

public event Action<HitObjectEaseEvent> HitObjectEaseEventAdded;
public event Action<HitObjectEaseEvent> HitObjectEaseEventRemoved;
public event Action<HitObjectEaseEvent> HitObjectEaseEventUpdated;

public event Action<ShaderEvent> ShaderEventAdded;
public event Action<ShaderEvent> ShaderEventRemoved;
public event Action<ShaderEvent> ShaderEventUpdated;
Expand Down Expand Up @@ -242,6 +246,11 @@ public void Add(ITimedObject obj)
HitObjectFadeEventAdded?.Invoke(hitFade);
break;

case HitObjectEaseEvent hitEase:
MapEvents.HitObjectEaseEvents.Add(hitEase);
HitObjectEaseEventAdded?.Invoke(hitEase);
break;

case ShaderEvent shaderEvent:
MapEvents.ShaderEvents.Add(shaderEvent);
ShaderEventAdded?.Invoke(shaderEvent);
Expand Down Expand Up @@ -311,6 +320,10 @@ public void Update(ITimedObject obj)
HitObjectFadeEventUpdated?.Invoke(hitFade);
break;

case HitObjectEaseEvent hitEase:
HitObjectEaseEventUpdated?.Invoke(hitEase);
break;

case ShaderEvent shaderEvent:
ShaderEventUpdated?.Invoke(shaderEvent);
break;
Expand Down Expand Up @@ -388,6 +401,11 @@ public void Remove(ITimedObject obj)
HitObjectFadeEventRemoved?.Invoke(hitFade);
break;

case HitObjectEaseEvent hitEase:
MapEvents.HitObjectEaseEvents.Remove(hitEase);
HitObjectEaseEventRemoved?.Invoke(hitEase);
break;

case ShaderEvent shaderEvent:
MapEvents.ShaderEvents.Remove(shaderEvent);
ShaderEventRemoved?.Invoke(shaderEvent);
Expand Down Expand Up @@ -475,6 +493,12 @@ public void ApplyOffsetToAll(float offset)
Update(hitFade);
}

foreach (var hitEase in MapEvents.HitObjectEaseEvents)
{
hitEase.Time += offset;
Update(hitEase);
}

foreach (var shaderEvent in MapEvents.ShaderEvents)
{
shaderEvent.Time += offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ protected override void RegisterEvents()
Map.HitObjectFadeEventRemoved += RemovePoint;
Map.MapEvents.HitObjectFadeEvents.ForEach(AddPoint);

Map.HitObjectEaseEventAdded += AddPoint;
Map.HitObjectEaseEventUpdated += UpdatePoint;
Map.HitObjectEaseEventRemoved += RemovePoint;
Map.MapEvents.HitObjectEaseEvents.ForEach(AddPoint);

Map.ShaderEventAdded += AddPoint;
Map.ShaderEventUpdated += UpdatePoint;
Map.ShaderEventRemoved += RemovePoint;
Expand Down Expand Up @@ -71,7 +76,8 @@ protected override PointListEntry CreateEntryFor(ITimedObject obj)
PlayfieldMoveEvent move => new PlayfieldMoveEntry(move),
PlayfieldFadeEvent fade => new PlayfieldFadeEntry(fade),
PlayfieldScaleEvent scale => new PlayfieldScaleEntry(scale),
HitObjectFadeEvent scale => new HitObjectFadeEntry(scale),
HitObjectFadeEvent fade => new HitObjectFadeEntry(fade),
HitObjectEaseEvent ease => new HitObjectEaseEntry(ease),
BeatPulseEvent pulse => new BeatPulseEntry(pulse),
PlayfieldRotateEvent rotate => new PlayfieldRotateEntry(rotate),
ShaderEvent shader => new ShaderEntry(shader),
Expand All @@ -91,6 +97,7 @@ protected override IEnumerable<AddButtonEntry> CreateAddEntries()
new("Playfield Rotate", FluXisColors.PlayfieldRotate, () => Create(new PlayfieldRotateEvent())),
new("Playfield Fade", FluXisColors.PlayfieldFade, () => Create(new PlayfieldFadeEvent())),
new("HitObject Fade", FluXisColors.HitObjectFade, () => Create(new HitObjectFadeEvent())),
new("HitObject Ease", FluXisColors.HitObjectEase, () => Create(new HitObjectEaseEvent())),
new("Beat Pulse", FluXisColors.BeatPulse, () => Create(new BeatPulseEvent())),
new("Note", FluXisColors.Note, () => Create(new NoteEvent())),
new("Shader", FluXisColors.Shader, () => Create(new ShaderEvent { ShaderName = "Bloom" }))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Linq;
using fluXis.Game.Graphics.Sprites;
using fluXis.Game.Graphics.UserInterface.Color;
using fluXis.Game.Map.Structures.Bases;
using fluXis.Game.Map.Structures.Events;
using fluXis.Game.Screens.Edit.Tabs.Shared.Points.List;
using fluXis.Game.Screens.Edit.Tabs.Shared.Points.Settings.Preset;
using osu.Framework.Graphics;

namespace fluXis.Game.Screens.Edit.Tabs.Design.Points.Entries;

public partial class HitObjectEaseEntry : PointListEntry
{
protected override string Text => "HitObject Ease";
protected override Colour4 Color => FluXisColors.HitObjectEase;

private HitObjectEaseEvent ease => Object as HitObjectEaseEvent;

public HitObjectEaseEntry(HitObjectEaseEvent obj)
: base(obj)
{
}

public override ITimedObject CreateClone() => new HitObjectEaseEvent
{
Time = Object.Time,
Easing = ease.Easing
};

protected override Drawable[] CreateValueContent()
{
return new Drawable[]
{
new FluXisSpriteText
{
Text = $"{ease.Easing}",
Colour = Color
}
};
}

protected override IEnumerable<Drawable> CreateSettings()
{
return base.CreateSettings().Concat(new Drawable[]
{
new PointSettingsEasing<HitObjectEaseEvent>(Map, ease)
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public partial class DrawableHitObject : CompositeDrawable
protected double ScrollVelocityTime { get; private set; }
protected double ScrollVelocityEndTime { get; private set; }

private Easing easing = Easing.None;

public FluXisGameplayKeybind Keybind { get; set; }

public virtual bool CanBeRemoved => false;
Expand All @@ -49,6 +51,7 @@ private void load()

ScrollVelocityTime = ObjectManager.ScrollVelocityPositionFromTime(Data.Time);
ScrollVelocityEndTime = ObjectManager.ScrollVelocityPositionFromTime(Data.EndTime);
easing = ObjectManager.EasingAtTime(Data.Time);
}

protected override void LoadComplete()
Expand All @@ -64,7 +67,7 @@ protected override void Update()
base.Update();

X = ObjectManager.PositionAtLane(Data.Lane);
Y = ObjectManager.PositionAtTime(ScrollVelocityTime);
Y = ObjectManager.PositionAtTime(ScrollVelocityTime, easing);
Width = ObjectManager.WidthOfLane(Data.Lane);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public override bool CanBeRemoved
private DrawableLongNoteTail tailPiece;
private DrawableLongNoteHead headPiece;

private Easing endEasing = Easing.None;

private bool missed;

private readonly Colour4 missTint = new(.4f, .4f, .4f, 1);
Expand All @@ -51,6 +53,8 @@ private void load()
headPiece = new DrawableLongNoteHead(Data)
};

endEasing = ObjectManager.EasingAtTime(Data.EndTime);

if (ObjectManager.UseSnapColors)
{
var startIdx = ObjectManager.GetSnapIndex(Data.Time);
Expand Down Expand Up @@ -102,7 +106,7 @@ protected override void Update()
if (IsBeingHeld.Value)
Y = ObjectManager.HitPosition;

var endY = ObjectManager.PositionAtTime(ScrollVelocityEndTime);
var endY = ObjectManager.PositionAtTime(ScrollVelocityEndTime, endEasing);
var height = Y - endY;

bodyPiece.Height = height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;

namespace fluXis.Game.Screens.Gameplay.Ruleset.HitObjects;

Expand Down Expand Up @@ -220,7 +221,19 @@ protected override void Update()
public float HitPosition => DrawHeight - laneSwitchManager.HitPosition;

public bool ShouldDisplay(double time) => ScrollVelocityPositionFromTime(time) <= ScrollVelocityPositionFromTime(Clock.CurrentTime) + DrawHeight * screen.Rate;
public float PositionAtTime(double time) => (float)(HitPosition - .5f * ((time - (float)CurrentTime) * ScrollSpeed));

public float PositionAtTime(double time, Easing ease = Easing.None)
{
var pos = HitPosition;
var y = (float)(pos - .5f * ((time - (float)CurrentTime) * ScrollSpeed));

if (ease <= Easing.None || y < 0 || y > pos)
return y;

var progress = y / pos;
y = Interpolation.ValueAt(progress, 0, pos, 0, 1, ease);
return float.IsFinite(y) ? y : 0;
}

public float PositionAtLane(int lane)
{
Expand All @@ -238,6 +251,17 @@ public float PositionAtLane(int lane)
return x;
}

public Easing EasingAtTime(double time)
{
var events = screen.MapEvents.HitObjectEaseEvents;

if (events.Count == 0)
return Easing.None;

var first = events.LastOrDefault(e => e.Time <= time);
return first?.Easing ?? Easing.None;
}

public float WidthOfLane(int lane) => laneSwitchManager.WidthFor(lane);

public bool IsFirstInColumn(DrawableHitObject hitObject) => HitObjects.FirstOrDefault(h => h.Data.Lane == hitObject.Data.Lane && h.Data.Time < hitObject.Data.Time) == null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public partial class TimingLine : Box

public double OriginalTime { get; }
private double scrollVelocityTime;
private Easing easing = Easing.None;

public TimingLine(double time)
{
Expand All @@ -25,10 +26,11 @@ private void load()
Origin = Anchor.BottomLeft;

scrollVelocityTime = playfield.Manager.ScrollVelocityPositionFromTime(OriginalTime);
easing = playfield.Manager.EasingAtTime(OriginalTime);
}

protected override void Update()
{
Y = playfield.Manager.PositionAtTime(scrollVelocityTime);
Y = playfield.Manager.PositionAtTime(scrollVelocityTime, easing);
}
}

0 comments on commit 7c67c94

Please sign in to comment.