mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:52:57 +08:00
Centralise and share bar line generation code between rulesets (#6054)
Centralise and share bar line generation code between rulesets
This commit is contained in:
commit
c27eed0195
@ -15,6 +15,7 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -114,8 +115,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
var obj = new BarLine
|
var obj = new BarLine
|
||||||
{
|
{
|
||||||
StartTime = Time.Current + 2000,
|
StartTime = Time.Current + 2000,
|
||||||
ControlPoint = new TimingControlPoint(),
|
Major = major,
|
||||||
BeatIndex = major ? 0 : 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
@ -1,21 +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 osu.Game.Beatmaps.ControlPoints;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects
|
|
||||||
{
|
|
||||||
public class BarLine : ManiaHitObject
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The control point which this bar line is part of.
|
|
||||||
/// </summary>
|
|
||||||
public TimingControlPoint ControlPoint;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The index of the beat which this bar line represents within the control point.
|
|
||||||
/// This is a "major" bar line if <see cref="BeatIndex"/> % <see cref="TimingControlPoint.TimeSignature"/> == 0.
|
|
||||||
/// </summary>
|
|
||||||
public int BeatIndex;
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,6 +4,7 @@
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// Visualises a <see cref="BarLine"/>. Although this derives DrawableManiaHitObject,
|
/// Visualises a <see cref="BarLine"/>. Although this derives DrawableManiaHitObject,
|
||||||
/// this does not handle input/sound like a normal hit object.
|
/// this does not handle input/sound like a normal hit object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrawableBarLine : DrawableManiaHitObject<BarLine>
|
public class DrawableBarLine : DrawableHitObject<BarLine>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Height of major bar line triangles.
|
/// Height of major bar line triangles.
|
||||||
@ -40,9 +41,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
Colour = new Color4(255, 204, 33, 255),
|
Colour = new Color4(255, 204, 33, 255),
|
||||||
});
|
});
|
||||||
|
|
||||||
bool isMajor = barLine.BeatIndex % (int)barLine.ControlPoint.TimeSignature == 0;
|
if (barLine.Major)
|
||||||
|
|
||||||
if (isMajor)
|
|
||||||
{
|
{
|
||||||
AddInternal(new EquilateralTriangle
|
AddInternal(new EquilateralTriangle
|
||||||
{
|
{
|
||||||
@ -65,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMajor && barLine.BeatIndex % 2 == 1)
|
if (!barLine.Major)
|
||||||
Alpha = 0.2f;
|
Alpha = 0.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
@ -19,8 +16,8 @@ using osu.Game.Rulesets.Mania.Objects.Drawables;
|
|||||||
using osu.Game.Rulesets.Mania.Replays;
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
using osu.Game.Rulesets.Mania.Scoring;
|
using osu.Game.Rulesets.Mania.Scoring;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
@ -45,33 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||||
: base(ruleset, beatmap, mods)
|
: base(ruleset, beatmap, mods)
|
||||||
{
|
{
|
||||||
// Generate the bar lines
|
BarLines = new BarLineGenerator(Beatmap).BarLines;
|
||||||
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
|
|
||||||
|
|
||||||
var timingPoints = Beatmap.ControlPointInfo.TimingPoints;
|
|
||||||
var barLines = new List<BarLine>();
|
|
||||||
|
|
||||||
for (int i = 0; i < timingPoints.Count; i++)
|
|
||||||
{
|
|
||||||
TimingControlPoint point = timingPoints[i];
|
|
||||||
|
|
||||||
// Stop on the beat before the next timing point, or if there is no next timing point stop slightly past the last object
|
|
||||||
double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - point.BeatLength : lastObjectTime + point.BeatLength * (int)point.TimeSignature;
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++)
|
|
||||||
{
|
|
||||||
barLines.Add(new BarLine
|
|
||||||
{
|
|
||||||
StartTime = t,
|
|
||||||
ControlPoint = point,
|
|
||||||
BeatIndex = index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BarLines = barLines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
@ -1,9 +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.
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
|
||||||
{
|
|
||||||
public class BarLine : TaikoHitObject
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A line that scrolls alongside hit objects in the playfield and visualises control points.
|
/// A line that scrolls alongside hit objects in the playfield and visualises control points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrawableBarLine : DrawableHitObject<TaikoHitObject>
|
public class DrawableBarLine : DrawableHitObject<HitObject>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The width of the line tracker.
|
/// The width of the line tracker.
|
||||||
|
@ -5,6 +5,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
|
@ -5,19 +5,18 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Scoring;
|
using osu.Game.Rulesets.Taiko.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.Taiko.Replays;
|
using osu.Game.Rulesets.Taiko.Replays;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
@ -38,49 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
loadBarLines();
|
new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
||||||
}
|
|
||||||
|
|
||||||
private void loadBarLines()
|
|
||||||
{
|
|
||||||
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
|
||||||
double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime);
|
|
||||||
|
|
||||||
var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList();
|
|
||||||
|
|
||||||
if (timingPoints.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int currentIndex = 0;
|
|
||||||
int currentBeat = 0;
|
|
||||||
double time = timingPoints[currentIndex].Time;
|
|
||||||
|
|
||||||
while (time <= lastHitTime)
|
|
||||||
{
|
|
||||||
int nextIndex = currentIndex + 1;
|
|
||||||
|
|
||||||
if (nextIndex < timingPoints.Count && time > timingPoints[nextIndex].Time)
|
|
||||||
{
|
|
||||||
currentIndex = nextIndex;
|
|
||||||
time = timingPoints[currentIndex].Time;
|
|
||||||
currentBeat = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentPoint = timingPoints[currentIndex];
|
|
||||||
|
|
||||||
var barLine = new BarLine
|
|
||||||
{
|
|
||||||
StartTime = time,
|
|
||||||
};
|
|
||||||
|
|
||||||
barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
|
||||||
|
|
||||||
bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
|
|
||||||
Playfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
|
|
||||||
|
|
||||||
time += currentPoint.BeatLength * (int)currentPoint.TimeSignature;
|
|
||||||
currentBeat++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
||||||
|
16
osu.Game/Rulesets/Objects/BarLine.cs
Normal file
16
osu.Game/Rulesets/Objects/BarLine.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Objects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A hit object representing the end of a bar.
|
||||||
|
/// </summary>
|
||||||
|
public class BarLine : HitObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this barline is a prominent beat (based on time signature of beatmap).
|
||||||
|
/// </summary>
|
||||||
|
public bool Major;
|
||||||
|
}
|
||||||
|
}
|
58
osu.Game/Rulesets/Objects/BarLineGenerator.cs
Normal file
58
osu.Game/Rulesets/Objects/BarLineGenerator.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Objects
|
||||||
|
{
|
||||||
|
public class BarLineGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The generated bar lines.
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<BarLine> BarLines = new List<BarLine>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs and generates bar lines for provided beatmap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The beatmap to generate bar lines for.</param>
|
||||||
|
public BarLineGenerator(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
if (beatmap.HitObjects.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HitObject lastObject = beatmap.HitObjects.Last();
|
||||||
|
double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime);
|
||||||
|
|
||||||
|
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
|
||||||
|
|
||||||
|
if (timingPoints.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < timingPoints.Count; i++)
|
||||||
|
{
|
||||||
|
TimingControlPoint currentTimingPoint = timingPoints[i];
|
||||||
|
int currentBeat = 0;
|
||||||
|
|
||||||
|
// Stop on the beat before the next timing point, or if there is no next timing point stop slightly past the last object
|
||||||
|
double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - currentTimingPoint.BeatLength : lastHitTime + currentTimingPoint.BeatLength * (int)currentTimingPoint.TimeSignature;
|
||||||
|
|
||||||
|
double barLength = currentTimingPoint.BeatLength * (int)currentTimingPoint.TimeSignature;
|
||||||
|
|
||||||
|
for (double t = currentTimingPoint.Time; Precision.DefinitelyBigger(endTime, t); t += barLength, currentBeat++)
|
||||||
|
{
|
||||||
|
BarLines.Add(new BarLine
|
||||||
|
{
|
||||||
|
StartTime = t,
|
||||||
|
Major = currentBeat % (int)currentTimingPoint.TimeSignature == 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user