mirror of
https://github.com/ppy/osu.git
synced 2024-11-14 19:47:24 +08:00
Merge pull request #1095 from smoogipooo/taiko-timingchanges-2
Make taiko use the new ScrollingPlayfield.
This commit is contained in:
commit
1249cc8eb9
@ -14,6 +14,9 @@ using osu.Game.Rulesets.Taiko.UI;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Desktop.Tests.Beatmaps;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Desktop.Tests.Visual
|
namespace osu.Desktop.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -27,7 +30,7 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
protected override double TimePerAction => default_duration * 2;
|
protected override double TimePerAction => default_duration * 2;
|
||||||
|
|
||||||
private readonly Random rng = new Random(1337);
|
private readonly Random rng = new Random(1337);
|
||||||
private readonly TaikoPlayfield playfield;
|
private readonly TaikoRulesetContainer rulesetContainer;
|
||||||
private readonly Container playfieldContainer;
|
private readonly Container playfieldContainer;
|
||||||
|
|
||||||
public TestCaseTaikoPlayfield()
|
public TestCaseTaikoPlayfield()
|
||||||
@ -51,6 +54,25 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
AddStep("Height test 5", () => changePlayfieldSize(5));
|
AddStep("Height test 5", () => changePlayfieldSize(5));
|
||||||
AddStep("Reset height", () => changePlayfieldSize(6));
|
AddStep("Reset height", () => changePlayfieldSize(6));
|
||||||
|
|
||||||
|
var controlPointInfo = new ControlPointInfo();
|
||||||
|
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
|
||||||
|
|
||||||
|
WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap
|
||||||
|
{
|
||||||
|
HitObjects = new List<HitObject> { new CentreHit() },
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Difficulty = new BeatmapDifficulty(),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Artist = @"Unknown",
|
||||||
|
Title = @"Sample Beatmap",
|
||||||
|
Author = @"peppy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ControlPointInfo = controlPointInfo
|
||||||
|
});
|
||||||
|
|
||||||
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
|
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
|
||||||
|
|
||||||
Add(playfieldContainer = new Container
|
Add(playfieldContainer = new Container
|
||||||
@ -58,12 +80,9 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = TaikoPlayfield.DEFAULT_HEIGHT,
|
Height = 768,
|
||||||
Clock = new FramedClock(rateAdjustClock),
|
Clock = new FramedClock(rateAdjustClock),
|
||||||
Children = new[]
|
Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) }
|
||||||
{
|
|
||||||
playfield = new TaikoPlayfield()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,18 +147,18 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
playfield.OnJudgement(h);
|
rulesetContainer.Playfield.OnJudgement(h);
|
||||||
|
|
||||||
if (RNG.Next(10) == 0)
|
if (RNG.Next(10) == 0)
|
||||||
{
|
{
|
||||||
h.Judgement.SecondHit = true;
|
h.Judgement.SecondHit = true;
|
||||||
playfield.OnJudgement(h);
|
rulesetContainer.Playfield.OnJudgement(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMissJudgement()
|
private void addMissJudgement()
|
||||||
{
|
{
|
||||||
playfield.OnJudgement(new DrawableTestHit(new Hit())
|
rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit())
|
||||||
{
|
{
|
||||||
Judgement = new TaikoJudgement
|
Judgement = new TaikoJudgement
|
||||||
{
|
{
|
||||||
@ -151,22 +170,17 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
private void addBarLine(bool major, double delay = scroll_time)
|
private void addBarLine(bool major, double delay = scroll_time)
|
||||||
{
|
{
|
||||||
BarLine bl = new BarLine
|
BarLine bl = new BarLine { StartTime = rulesetContainer.Playfield.Time.Current + delay };
|
||||||
{
|
|
||||||
StartTime = playfield.Time.Current + delay,
|
|
||||||
ScrollTime = scroll_time
|
|
||||||
};
|
|
||||||
|
|
||||||
playfield.AddBarLine(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
|
rulesetContainer.Playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSwell(double duration = default_duration)
|
private void addSwell(double duration = default_duration)
|
||||||
{
|
{
|
||||||
playfield.Add(new DrawableSwell(new Swell
|
rulesetContainer.Playfield.Add(new DrawableSwell(new Swell
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
Duration = duration,
|
Duration = duration,
|
||||||
ScrollTime = scroll_time
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,43 +191,40 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
var d = new DrumRoll
|
var d = new DrumRoll
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
IsStrong = strong,
|
IsStrong = strong,
|
||||||
Duration = duration,
|
Duration = duration,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
playfield.Add(new DrawableDrumRoll(d));
|
rulesetContainer.Playfield.Add(new DrawableDrumRoll(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCentreHit(bool strong)
|
private void addCentreHit(bool strong)
|
||||||
{
|
{
|
||||||
Hit h = new Hit
|
Hit h = new Hit
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
IsStrong = strong
|
IsStrong = strong
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strong)
|
if (strong)
|
||||||
playfield.Add(new DrawableCentreHitStrong(h));
|
rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h));
|
||||||
else
|
else
|
||||||
playfield.Add(new DrawableCentreHit(h));
|
rulesetContainer.Playfield.Add(new DrawableCentreHit(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRimHit(bool strong)
|
private void addRimHit(bool strong)
|
||||||
{
|
{
|
||||||
Hit h = new Hit
|
Hit h = new Hit
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
IsStrong = strong
|
IsStrong = strong
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strong)
|
if (strong)
|
||||||
playfield.Add(new DrawableRimHitStrong(h));
|
rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h));
|
||||||
else
|
else
|
||||||
playfield.Add(new DrawableRimHit(h));
|
rulesetContainer.Playfield.Add(new DrawableRimHit(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
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 : Container
|
public class DrawableBarLine : DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The width of the line tracker.
|
/// The width of the line tracker.
|
||||||
@ -34,15 +35,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
protected readonly BarLine BarLine;
|
protected readonly BarLine BarLine;
|
||||||
|
|
||||||
public DrawableBarLine(BarLine barLine)
|
public DrawableBarLine(BarLine barLine)
|
||||||
|
: base(barLine)
|
||||||
{
|
{
|
||||||
BarLine = barLine;
|
BarLine = barLine;
|
||||||
|
|
||||||
Anchor = Anchor.CentreLeft;
|
Anchor = Anchor.CentreLeft;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.X;
|
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
|
||||||
Width = tracker_width;
|
Width = tracker_width;
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
@ -56,24 +56,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Alpha = 0.75f
|
Alpha = 0.75f
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LifetimeStart = BarLine.StartTime - BarLine.ScrollTime * 2;
|
|
||||||
LifetimeEnd = BarLine.StartTime + BarLine.ScrollTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
||||||
|
|
||||||
|
protected override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
|
||||||
this.Delay(BarLine.StartTime - Time.Current).FadeOut(base_fadeout_time * BarLine.ScrollTime / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateScrollPosition(double time) => this.MoveToX((float)((BarLine.StartTime - time) / BarLine.ScrollTime));
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
updateScrollPosition(Time.Current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ using OpenTK;
|
|||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -31,30 +32,29 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
public DrawableDrumRoll(DrumRoll drumRoll)
|
public DrawableDrumRoll(DrumRoll drumRoll)
|
||||||
: base(drumRoll)
|
: base(drumRoll)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
Width = (float)HitObject.Duration;
|
||||||
AutoSizeAxes = Axes.X;
|
|
||||||
|
Container<DrawableDrumRollTick> tickContainer;
|
||||||
|
MainPiece.Add(tickContainer = new Container<DrawableDrumRollTick>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
RelativeChildOffset = new Vector2((float)HitObject.StartTime, 0),
|
||||||
|
RelativeChildSize = new Vector2((float)HitObject.Duration, 1)
|
||||||
|
});
|
||||||
|
|
||||||
foreach (var tick in drumRoll.Ticks)
|
foreach (var tick in drumRoll.Ticks)
|
||||||
{
|
{
|
||||||
var newTick = new DrawableDrumRollTick(tick)
|
var newTick = new DrawableDrumRollTick(tick);
|
||||||
{
|
|
||||||
X = (float)((tick.StartTime - HitObject.StartTime) / HitObject.Duration)
|
|
||||||
};
|
|
||||||
|
|
||||||
newTick.OnJudgement += onTickJudgement;
|
newTick.OnJudgement += onTickJudgement;
|
||||||
|
|
||||||
AddNested(newTick);
|
AddNested(newTick);
|
||||||
MainPiece.Add(newTick);
|
tickContainer.Add(newTick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
|
||||||
|
|
||||||
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece
|
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
|
||||||
{
|
|
||||||
Length = (float)(HitObject.Duration / HitObject.ScrollTime),
|
|
||||||
PlayfieldLengthReference = () => Parent.DrawSize.X
|
|
||||||
};
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
@ -63,17 +63,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
accentDarkColour = colours.YellowDarker;
|
accentDarkColour = colours.YellowDarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
// This is naive, however it's based on the reasoning that the hit target
|
|
||||||
// is further than mid point of the play field, so the time taken to scroll in should always
|
|
||||||
// be greater than the time taken to scroll out to the left of the screen.
|
|
||||||
// Thus, using PreEmpt here is enough for the drum roll to completely scroll out.
|
|
||||||
LifetimeEnd = HitObject.EndTime + HitObject.ScrollTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
|
private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
|
||||||
{
|
{
|
||||||
if (obj.Judgement.Result == HitResult.Hit)
|
if (obj.Judgement.Result == HitResult.Hit)
|
||||||
|
@ -15,9 +15,21 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
public DrawableDrumRollTick(DrumRollTick tick)
|
public DrawableDrumRollTick(DrumRollTick tick)
|
||||||
: base(tick)
|
: base(tick)
|
||||||
{
|
{
|
||||||
|
// Because ticks aren't added by the ScrollingPlayfield, we need to set the following properties ourselves
|
||||||
|
RelativePositionAxes = Axes.X;
|
||||||
|
X = (float)tick.StartTime;
|
||||||
|
|
||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override TaikoPiece CreateMainPiece() => new TickPiece
|
protected override TaikoPiece CreateMainPiece() => new TickPiece
|
||||||
{
|
{
|
||||||
Filled = HitObject.FirstTick
|
Filled = HitObject.FirstTick
|
||||||
@ -47,11 +59,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateScrollPosition(double time)
|
|
||||||
{
|
|
||||||
// Ticks don't move
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool HandleKeyPress(Key key)
|
protected override bool HandleKeyPress(Key key)
|
||||||
{
|
{
|
||||||
return Judgement.Result == HitResult.None && UpdateJudgement(true);
|
return Judgement.Result == HitResult.None && UpdateJudgement(true);
|
||||||
|
@ -29,6 +29,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckJudgement(bool userTriggered)
|
protected override void CheckJudgement(bool userTriggered)
|
||||||
{
|
{
|
||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
|
@ -118,7 +118,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
});
|
});
|
||||||
|
|
||||||
MainPiece.Add(symbol = new SwellSymbolPiece());
|
MainPiece.Add(symbol = new SwellSymbolPiece());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -129,6 +128,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckJudgement(bool userTriggered)
|
protected override void CheckJudgement(bool userTriggered)
|
||||||
{
|
{
|
||||||
if (userTriggered)
|
if (userTriggered)
|
||||||
@ -189,20 +196,22 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Expire();
|
Expire();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateScrollPosition(double time)
|
protected override void Update()
|
||||||
{
|
{
|
||||||
// Make the swell stop at the hit target
|
base.Update();
|
||||||
double t = Math.Min(HitObject.StartTime, time);
|
|
||||||
|
|
||||||
|
// Make the swell stop at the hit target
|
||||||
|
X = (float)Math.Max(Time.Current, HitObject.StartTime);
|
||||||
|
|
||||||
|
double t = Math.Min(HitObject.StartTime, Time.Current);
|
||||||
if (t == HitObject.StartTime && !hasStarted)
|
if (t == HitObject.StartTime && !hasStarted)
|
||||||
{
|
{
|
||||||
OnStart?.Invoke();
|
OnStart?.Invoke();
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.UpdateScrollPosition(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override bool HandleKeyPress(Key key)
|
protected override bool HandleKeyPress(Key key)
|
||||||
{
|
{
|
||||||
if (Judgement.Result != HitResult.None)
|
if (Judgement.Result != HitResult.None)
|
||||||
|
@ -12,7 +12,7 @@ using OpenTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
where TaikoHitType : TaikoHitObject
|
where TaikoHitType : TaikoHitObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -38,30 +38,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||||
|
|
||||||
RelativePositionAxes = Axes.X;
|
|
||||||
|
|
||||||
Add(MainPiece = CreateMainPiece());
|
Add(MainPiece = CreateMainPiece());
|
||||||
MainPiece.KiaiMode = HitObject.Kiai;
|
MainPiece.KiaiMode = HitObject.Kiai;
|
||||||
|
|
||||||
LifetimeStart = HitObject.StartTime - HitObject.ScrollTime * 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
||||||
|
|
||||||
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the scroll position of the DrawableHitObject relative to the offset between
|
|
||||||
/// a time value and the HitObject's StartTime.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="time"></param>
|
|
||||||
protected virtual void UpdateScrollPosition(double time) => X = (float)((HitObject.StartTime - time) / HitObject.ScrollTime);
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
UpdateScrollPosition(Time.Current);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool HandleKeyPress(Key key) => false;
|
protected virtual bool HandleKeyPress(Key key) => false;
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
|
@ -1,23 +1,12 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class ElongatedCirclePiece : CirclePiece
|
public class ElongatedCirclePiece : CirclePiece
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// As we are being used to define the absolute size of hits, we need to be given a relative reference of our containing playfield container.
|
|
||||||
/// </summary>
|
|
||||||
public Func<float> PlayfieldLengthReference;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The length of this piece as a multiple of the value returned by <see cref="PlayfieldLengthReference"/>
|
|
||||||
/// </summary>
|
|
||||||
public float Length;
|
|
||||||
|
|
||||||
public ElongatedCirclePiece()
|
public ElongatedCirclePiece()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
@ -35,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
Right = padding,
|
Right = padding,
|
||||||
};
|
};
|
||||||
|
|
||||||
Width = (PlayfieldLengthReference?.Invoke() ?? 0) * Length + DrawHeight;
|
Width = Parent.DrawSize.X + DrawHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
ret.Add(new DrumRollTick
|
ret.Add(new DrumRollTick
|
||||||
{
|
{
|
||||||
FirstTick = first,
|
FirstTick = first,
|
||||||
ScrollTime = ScrollTime,
|
|
||||||
TickSpacing = tickSpacing,
|
TickSpacing = tickSpacing,
|
||||||
StartTime = t,
|
StartTime = t,
|
||||||
IsStrong = IsStrong,
|
IsStrong = IsStrong,
|
||||||
|
@ -24,16 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a <see cref="TimingControlPoint.BeatLength"/> of 1000ms.
|
|
||||||
/// </summary>
|
|
||||||
private const double scroll_time = 6000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Our adjusted <see cref="scroll_time"/> taking into consideration local <see cref="TimingControlPoint.BeatLength"/> and other speed multipliers.
|
|
||||||
/// </summary>
|
|
||||||
public double ScrollTime;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this HitObject is a "strong" type.
|
/// Whether this HitObject is a "strong" type.
|
||||||
/// Strong hit objects give more points for hitting the hit object with both keys.
|
/// Strong hit objects give more points for hitting the hit object with both keys.
|
||||||
@ -49,12 +39,8 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
{
|
{
|
||||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||||
|
|
||||||
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
|
|
||||||
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
|
|
||||||
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
||||||
|
|
||||||
ScrollTime = scroll_time * (timingPoint.BeatLength * difficultyPoint.SpeedMultiplier / 1000) / difficulty.SliderMultiplier;
|
|
||||||
|
|
||||||
Kiai |= effectPoint.KiaiMode;
|
Kiai |= effectPoint.KiaiMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoPlayfield : Playfield<TaikoHitObject, TaikoJudgement>
|
public class TaikoPlayfield : ScrollingPlayfield<TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
||||||
@ -35,14 +35,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float left_area_size = 240;
|
private const float left_area_size = 240;
|
||||||
|
|
||||||
protected override Container<Drawable> Content => hitObjectContainer;
|
|
||||||
|
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||||
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
||||||
private readonly Container<DrawableBarLine> barLineContainer;
|
|
||||||
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
||||||
|
|
||||||
private readonly Container hitObjectContainer;
|
protected override Container<Drawable> Content => content;
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
private readonly Container topLevelHitContainer;
|
private readonly Container topLevelHitContainer;
|
||||||
|
|
||||||
private readonly Container overlayBackgroundContainer;
|
private readonly Container overlayBackgroundContainer;
|
||||||
@ -52,6 +52,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
|
||||||
public TaikoPlayfield()
|
public TaikoPlayfield()
|
||||||
|
: base(Axes.X)
|
||||||
{
|
{
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
@ -96,10 +97,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
FillMode = FillMode.Fit,
|
FillMode = FillMode.Fit,
|
||||||
BlendingMode = BlendingMode.Additive,
|
BlendingMode = BlendingMode.Additive,
|
||||||
},
|
},
|
||||||
barLineContainer = new Container<DrawableBarLine>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new HitTarget
|
new HitTarget
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
@ -107,7 +104,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
FillMode = FillMode.Fit
|
FillMode = FillMode.Fit
|
||||||
},
|
},
|
||||||
hitObjectContainer = new Container
|
content = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
@ -181,6 +178,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
VisibleTimeRange.Value = 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -205,11 +204,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
|
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddBarLine(DrawableBarLine barLine)
|
|
||||||
{
|
|
||||||
barLineContainer.Add(barLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)
|
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)
|
||||||
{
|
{
|
||||||
bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
|
bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
|
||||||
@ -230,7 +224,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
if (!secondHit)
|
if (!secondHit)
|
||||||
{
|
{
|
||||||
if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
|
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
|
// If we're far enough away from the left stage, we should bring outselves in front of it
|
||||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||||
|
@ -21,7 +21,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoRulesetContainer : RulesetContainer<TaikoHitObject, TaikoJudgement>
|
public class TaikoRulesetContainer : ScrollingRulesetContainer<TaikoPlayfield, TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||||
@ -36,11 +36,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
private void loadBarLines()
|
private void loadBarLines()
|
||||||
{
|
{
|
||||||
var taikoPlayfield = Playfield as TaikoPlayfield;
|
|
||||||
|
|
||||||
if (taikoPlayfield == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
||||||
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
||||||
|
|
||||||
@ -72,7 +67,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty);
|
barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty);
|
||||||
|
|
||||||
bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
|
bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
|
||||||
taikoPlayfield.AddBarLine(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
|
Playfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
|
||||||
|
|
||||||
double bl = currentPoint.BeatLength;
|
double bl = currentPoint.BeatLength;
|
||||||
if (bl < 800)
|
if (bl < 800)
|
||||||
|
@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
protected DrawableScrollingHitObject(TObject hitObject)
|
protected DrawableScrollingHitObject(TObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal Axes ScrollingAxes;
|
internal Axes ScrollingAxes;
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control point that defines the speed adjustments for this container. This is set by the <see cref="SpeedAdjustmentContainer"/>.
|
/// The control point that defines the speed adjustments for this container. This is set by the <see cref="SpeedAdjustmentContainer"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,6 +34,8 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Axes ScrollingAxes { get; internal set; }
|
public Axes ScrollingAxes { get; internal set; }
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplierControlPoint"/> that defines the speed adjustments.
|
/// The <see cref="MultiplierControlPoint"/> that defines the speed adjustments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Transforms;
|
using osu.Framework.Graphics.Transforms;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
@ -154,7 +155,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// Hit objects that are to be re-processed on the next update.
|
/// Hit objects that are to be re-processed on the next update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<DrawableHitObject> queuedHitObjects = new List<DrawableHitObject>();
|
private readonly List<DrawableHitObject> queuedHitObjects = new List<DrawableHitObject>();
|
||||||
private readonly List<SpeedAdjustmentContainer> speedAdjustments = new List<SpeedAdjustmentContainer>();
|
private readonly Container<SpeedAdjustmentContainer> speedAdjustments;
|
||||||
|
|
||||||
private readonly Axes scrollingAxes;
|
private readonly Axes scrollingAxes;
|
||||||
|
|
||||||
@ -165,6 +166,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public ScrollingHitObjectContainer(Axes scrollingAxes)
|
public ScrollingHitObjectContainer(Axes scrollingAxes)
|
||||||
{
|
{
|
||||||
this.scrollingAxes = scrollingAxes;
|
this.scrollingAxes = scrollingAxes;
|
||||||
|
|
||||||
|
AddInternal(speedAdjustments = new Container<SpeedAdjustmentContainer> { RelativeSizeAxes = Axes.Both });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -176,9 +179,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
speedAdjustment.ScrollingAxes = scrollingAxes;
|
speedAdjustment.ScrollingAxes = scrollingAxes;
|
||||||
speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange);
|
speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange);
|
||||||
speedAdjustment.Reversed.BindTo(Reversed);
|
speedAdjustment.Reversed.BindTo(Reversed);
|
||||||
|
|
||||||
speedAdjustments.Add(speedAdjustment);
|
speedAdjustments.Add(speedAdjustment);
|
||||||
AddInternal(speedAdjustment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DrawableHitObject> Objects => speedAdjustments.SelectMany(s => s.Children);
|
public override IEnumerable<DrawableHitObject> Objects => speedAdjustments.SelectMany(s => s.Children);
|
||||||
@ -210,13 +211,13 @@ namespace osu.Game.Rulesets.UI
|
|||||||
var hitObject = queuedHitObjects[i];
|
var hitObject = queuedHitObjects[i];
|
||||||
|
|
||||||
var target = adjustmentContainerFor(hitObject);
|
var target = adjustmentContainerFor(hitObject);
|
||||||
if (target != null)
|
if (target == null)
|
||||||
{
|
continue;
|
||||||
|
|
||||||
target.Add(hitObject);
|
target.Add(hitObject);
|
||||||
queuedHitObjects.RemoveAt(i);
|
queuedHitObjects.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment active at the start time
|
/// Finds the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment active at the start time
|
||||||
|
Loading…
Reference in New Issue
Block a user