mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 12:33:01 +08:00
Add slider ticks.
This commit is contained in:
parent
3caa6ee5d2
commit
3e7208c8a4
@ -1,12 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenTK;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Modes.Objects.Drawables;
|
||||
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
|
||||
using OpenTK;
|
||||
using osu.Framework.Input;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
{
|
||||
@ -22,6 +23,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
SliderBall ball;
|
||||
|
||||
SliderBouncer bouncer1, bouncer2;
|
||||
SliderTicksRenderer ticks;
|
||||
|
||||
public DrawableSlider(Slider s) : base(s)
|
||||
{
|
||||
@ -34,6 +36,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
Position = s.StackedPosition,
|
||||
PathWidth = s.Scale * 64,
|
||||
},
|
||||
ticks = new SliderTicksRenderer
|
||||
{
|
||||
Position = s.StackedPosition,
|
||||
StartTime = s.StartTime,
|
||||
RepeatDuration = s.Curve.Length / s.Velocity,
|
||||
Ticks = s.Ticks,
|
||||
},
|
||||
bouncer1 = new SliderBouncer(s, false)
|
||||
{
|
||||
Position = s.Curve.PositionAt(1),
|
||||
@ -96,6 +105,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
initialCircle.Position = slider.Curve.PositionAt(progress);
|
||||
|
||||
components.ForEach(c => c.UpdateProgress(progress, repeat));
|
||||
ticks.ShouldHit = ball.Tracking;
|
||||
}
|
||||
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
@ -105,8 +115,22 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
|
||||
if (!userTriggered && Time.Current >= HitObject.EndTime)
|
||||
{
|
||||
j.Score = sc.Score;
|
||||
j.Result = sc.Result;
|
||||
var ticksCount = ticks.Children.Count() + 1;
|
||||
var ticksHit = ticks.Children.Count(t => t.Judgement.Result == HitResult.Hit);
|
||||
if (sc.Result == HitResult.Hit)
|
||||
ticksHit++;
|
||||
|
||||
var hitFraction = (double)ticksHit / ticksCount;
|
||||
if (hitFraction == 1 && sc.Score == OsuScoreResult.Hit300)
|
||||
j.Score = OsuScoreResult.Hit300;
|
||||
else if (hitFraction >= 0.5 && sc.Score >= OsuScoreResult.Hit100)
|
||||
j.Score = OsuScoreResult.Hit100;
|
||||
else if (hitFraction > 0)
|
||||
j.Score = OsuScoreResult.Hit50;
|
||||
else
|
||||
j.Score = OsuScoreResult.Miss;
|
||||
|
||||
j.Result = j.Score != OsuScoreResult.Miss ? HitResult.Hit : HitResult.Miss;
|
||||
}
|
||||
}
|
||||
|
||||
|
92
osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs
Normal file
92
osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Game.Modes.Objects.Drawables;
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
public class DrawableSliderTick : DrawableOsuHitObject
|
||||
{
|
||||
private SliderTick sliderTick;
|
||||
|
||||
public double FadeInTime;
|
||||
public double FadeOutTime;
|
||||
|
||||
public bool ShouldHit;
|
||||
|
||||
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
|
||||
{
|
||||
this.sliderTick = sliderTick;
|
||||
|
||||
Size = new Vector2(16) * sliderTick.Scale;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = Size.X / 2;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
BorderThickness = 2;
|
||||
BorderColour = Color4.White;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = sliderTick.Colour,
|
||||
Alpha = 0.3f,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
{
|
||||
if (Judgement.TimeOffset >= 0)
|
||||
Judgement.Result = ShouldHit ? HitResult.Hit : HitResult.Miss;
|
||||
}
|
||||
|
||||
protected override void UpdatePreemptState()
|
||||
{
|
||||
var animIn = Math.Min(150, sliderTick.StartTime - FadeInTime);
|
||||
|
||||
ScaleTo(0.5f);
|
||||
ScaleTo(1.2f, animIn);
|
||||
FadeIn(animIn);
|
||||
|
||||
Delay(animIn);
|
||||
ScaleTo(1, 150, EasingTypes.Out);
|
||||
|
||||
Delay(-animIn);
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
|
||||
base.UpdateState(state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Idle:
|
||||
Delay(FadeOutTime - sliderTick.StartTime);
|
||||
FadeOut();
|
||||
break;
|
||||
case ArmedState.Miss:
|
||||
FadeTo(0.6f);
|
||||
Delay(FadeOutTime - sliderTick.StartTime);
|
||||
FadeOut();
|
||||
break;
|
||||
case ArmedState.Hit:
|
||||
FadeOut();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
osu.Game.Modes.Osu/Objects/Drawables/SliderTicksRenderer.cs
Normal file
74
osu.Game.Modes.Osu/Objects/Drawables/SliderTicksRenderer.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
public class SliderTicksRenderer : Container<DrawableSliderTick>
|
||||
{
|
||||
private double startTime;
|
||||
public double StartTime
|
||||
{
|
||||
get { return startTime; }
|
||||
set
|
||||
{
|
||||
startTime = value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private double repeatDuration;
|
||||
public double RepeatDuration
|
||||
{
|
||||
get { return repeatDuration; }
|
||||
set
|
||||
{
|
||||
repeatDuration = value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<SliderTick> ticks;
|
||||
public IEnumerable<SliderTick> Ticks
|
||||
{
|
||||
get { return ticks; }
|
||||
set
|
||||
{
|
||||
ticks = value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldHit
|
||||
{
|
||||
set
|
||||
{
|
||||
foreach (var tick in Children)
|
||||
tick.ShouldHit = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void update()
|
||||
{
|
||||
Clear();
|
||||
if (ticks == null || repeatDuration == 0)
|
||||
return;
|
||||
|
||||
foreach (var tick in ticks)
|
||||
{
|
||||
var repeatStartTime = startTime + tick.RepeatIndex * repeatDuration;
|
||||
var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? DrawableOsuHitObject.TIME_FADEIN : DrawableOsuHitObject.TIME_FADEIN / 2);
|
||||
var fadeOutTime = repeatStartTime + repeatDuration;
|
||||
|
||||
Add(new DrawableSliderTick(tick)
|
||||
{
|
||||
FadeInTime = fadeInTime,
|
||||
FadeOutTime = fadeOutTime,
|
||||
Position = tick.Position,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using OpenTK;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using osu.Game.Beatmaps.Samples;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects
|
||||
{
|
||||
@ -25,17 +28,66 @@ namespace osu.Game.Modes.Osu.Objects
|
||||
}
|
||||
|
||||
public double Velocity;
|
||||
public double TickDistance;
|
||||
|
||||
public override void SetDefaultsFromBeatmap(Beatmap beatmap)
|
||||
{
|
||||
base.SetDefaultsFromBeatmap(beatmap);
|
||||
|
||||
Velocity = 100 / beatmap.BeatLengthAt(StartTime, true) * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier;
|
||||
var baseDifficulty = beatmap.BeatmapInfo.BaseDifficulty;
|
||||
|
||||
var startBeatLength = beatmap.BeatLengthAt(StartTime);
|
||||
var multipliedStartBeatLength = beatmap.BeatLengthAt(StartTime, true);
|
||||
|
||||
Velocity = 100 / multipliedStartBeatLength * baseDifficulty.SliderMultiplier;
|
||||
TickDistance = (100 * baseDifficulty.SliderMultiplier) / baseDifficulty.SliderTickRate / (multipliedStartBeatLength / startBeatLength);
|
||||
}
|
||||
|
||||
public int RepeatCount;
|
||||
|
||||
public SliderCurve Curve;
|
||||
|
||||
public IEnumerable<SliderTick> Ticks
|
||||
{
|
||||
get
|
||||
{
|
||||
var length = Curve.Length;
|
||||
var tickDistance = Math.Min(TickDistance, length);
|
||||
var repeatDuration = length / Velocity;
|
||||
|
||||
var minDistanceFromEnd = Velocity * 0.01;
|
||||
|
||||
for (var repeat = 0; repeat < RepeatCount; repeat++)
|
||||
{
|
||||
var repeatStartTime = StartTime + repeat * repeatDuration;
|
||||
var reversed = repeat % 2 == 1;
|
||||
|
||||
for (var d = tickDistance; d <= length; d += tickDistance)
|
||||
{
|
||||
if (d > length - minDistanceFromEnd)
|
||||
break;
|
||||
|
||||
var distanceProgress = d / length;
|
||||
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
|
||||
|
||||
yield return new SliderTick
|
||||
{
|
||||
RepeatIndex = repeat,
|
||||
StartTime = repeatStartTime + timeProgress * repeatDuration,
|
||||
Position = Curve.PositionAt(distanceProgress) - StackedPosition,
|
||||
StackHeight = StackHeight,
|
||||
Scale = Scale,
|
||||
Colour = Colour,
|
||||
Sample = new HitSampleInfo
|
||||
{
|
||||
Type = SampleType.None,
|
||||
Set = SampleSet.Soft,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CurveTypes
|
||||
|
9
osu.Game.Modes.Osu/Objects/SliderTick.cs
Normal file
9
osu.Game.Modes.Osu/Objects/SliderTick.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects
|
||||
{
|
||||
public class SliderTick : OsuHitObject
|
||||
{
|
||||
public int RepeatIndex { get; set; }
|
||||
}
|
||||
}
|
@ -47,6 +47,7 @@
|
||||
<Compile Include="Objects\CircularArcApproximator.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableOsuHitObject.cs" />
|
||||
<Compile Include="Objects\Drawables\Connections\ConnectionRenderer.cs" />
|
||||
<Compile Include="Objects\Drawables\SliderTicksRenderer.cs" />
|
||||
<Compile Include="Objects\Drawables\Connections\FollowPointRenderer.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\ApproachCircle.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\CirclePiece.cs" />
|
||||
@ -57,6 +58,7 @@
|
||||
<Compile Include="Objects\Drawables\Pieces\GlowPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\HitExplosion.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\NumberPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableSliderTick.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\RingPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SliderBouncer.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\Triangles.cs" />
|
||||
@ -64,6 +66,7 @@
|
||||
<Compile Include="Objects\Drawables\Pieces\SliderBody.cs" />
|
||||
<Compile Include="Objects\OsuHitObjectParser.cs" />
|
||||
<Compile Include="Objects\SliderCurve.cs" />
|
||||
<Compile Include="Objects\SliderTick.cs" />
|
||||
<Compile Include="OsuScore.cs" />
|
||||
<Compile Include="OsuScoreProcessor.cs" />
|
||||
<Compile Include="UI\OsuComboCounter.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user