public SliderBall(Slider slider, DrawableSlider drawableSlider = null) { this.drawableSlider = drawableSlider; this.slider = slider; Blending = BlendingParameters.Additive; Origin = Anchor.Centre; Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Children = new[] { FollowCircle = new FollowCircleContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both, Alpha = 0, Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()), }, new CircularContainer { Masking = true, RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = 1, Child = new Container { RelativeSizeAxes = Axes.Both, Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()), } } }; }
private void retrieveSlider(int index) { AddStep("retrieve slider at index", () => slider = (Slider)beatmap.HitObjects[index]); addSeekStep(() => slider); AddUntilStep("retrieve drawable slider", () => (drawableSlider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == slider)) != null); }
private void addSlider(Slider slider, float circleSize, double speedMultiplier) { var cpi = new ControlPointInfo(); cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier }); slider.ApplyDefaults(cpi, new BeatmapDifficulty { CircleSize = circleSize, SliderTickRate = 3 }); var drawable = new DrawableSlider(slider) { Anchor = Anchor.Centre, Depth = depthIndex++ }; foreach (var mod in Mods.OfType <IApplicableToDrawableHitObjects>()) { mod.ApplyToDrawableHitObjects(new[] { drawable }); } drawable.OnJudgement += onJudgement; Add(drawable); }
private void addObjectsStep(Func <OsuHitObject[]> ctorFunc) { AddStep("add hitobjects", () => { var objects = ctorFunc(); for (int i = 0; i < objects.Length; i++) { objects[i].StartTime = Time.Current + 1000 + 500 * (i + 1); objects[i].ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); DrawableOsuHitObject drawableObject = null; switch (objects[i]) { case HitCircle circle: drawableObject = new DrawableHitCircle(circle); break; case Slider slider: drawableObject = new DrawableSlider(slider); break; case Spinner spinner: drawableObject = new DrawableSpinner(spinner); break; } hitObjectContainer.Add(drawableObject); followPointRenderer.AddFollowPoints(objects[i]); } }); }
public void TestSliderAnimationDisable() { Slider slider = null; DrawableSlider drawableSlider = null; DrawableSliderRepeat sliderRepeat = null; AddStep("retrieve first slider with repeats", () => slider = getSliderWithRepeats(0)); toggleAnimations(true); seekSmoothlyTo(() => slider.StartTime + slider.SpanDuration + 10); retrieveDrawables(); assertFutureTransforms(() => sliderRepeat, true); AddStep("retrieve second slider with repeats", () => slider = getSliderWithRepeats(1)); toggleAnimations(false); seekSmoothlyTo(() => slider.StartTime + slider.SpanDuration + 10); retrieveDrawables(); assertFutureTransforms(() => sliderRepeat.Arrow, false); seekSmoothlyTo(() => slider.GetEndTime()); AddAssert("slider has longer fade-out applied", () => { var alphaTransform = drawableSlider.Transforms.Last(t => t.TargetMember == nameof(Alpha)); return(alphaTransform.EndTime - alphaTransform.StartTime == DrawableOsuEditorRuleset.EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION); }); void retrieveDrawables() => AddStep("retrieve drawables", () => { drawableSlider = (DrawableSlider)getDrawableObjectFor(slider); sliderRepeat = (DrawableSliderRepeat)getDrawableObjectFor(slider.NestedHitObjects.OfType <SliderRepeat>().First()); }); }
public void TestSlidingSampleStopsOnSeek() { DrawableSlider slider = null; DrawableSample[] samples = null; AddStep("get first slider", () => { slider = Editor.ChildrenOfType <DrawableSlider>().OrderBy(s => s.HitObject.StartTime).First(); samples = slider.ChildrenOfType <DrawableSample>().ToArray(); }); AddStep("start playback", () => EditorClock.Start()); AddUntilStep("wait for slider sliding then seek", () => { if (!slider.Tracking.Value) { return(false); } if (!samples.Any(s => s.Playing)) { return(false); } EditorClock.Seek(20000); return(true); }); AddAssert("slider samples are not playing", () => samples.Length == 5 && samples.All(s => s.Played && !s.Playing)); }
public void TestSlidingSampleStopsOnSeek() { DrawableSlider slider = null; PoolableSkinnableSample[] loopingSamples = null; PoolableSkinnableSample[] onceOffSamples = null; AddStep("get first slider", () => { slider = Editor.ChildrenOfType <DrawableSlider>().OrderBy(s => s.HitObject.StartTime).First(); onceOffSamples = slider.ChildrenOfType <PoolableSkinnableSample>().Where(s => !s.Looping).ToArray(); loopingSamples = slider.ChildrenOfType <PoolableSkinnableSample>().Where(s => s.Looping).ToArray(); }); AddStep("start playback", () => EditorClock.Start()); AddUntilStep("wait for slider sliding then seek", () => { if (!slider.Tracking.Value) { return(false); } if (!loopingSamples.Any(s => s.Playing)) { return(false); } EditorClock.Seek(20000); return(true); }); AddAssert("non-looping samples are playing", () => onceOffSamples.Length == 4 && loopingSamples.All(s => s.Played || s.Playing)); AddAssert("looping samples are not playing", () => loopingSamples.Length == 1 && loopingSamples.All(s => s.Played && !s.Playing)); }
public void TestApplyNewSlider() { DrawableSlider dho = null; AddStep("create slider", () => Child = dho = new DrawableSlider(prepareObject(new Slider { Position = new Vector2(256, 192), IndexInCurrentCombo = 0, StartTime = Time.Current, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(150, 100), new Vector2(300, 0), }) }))); AddWaitStep("wait for progression", 1); AddStep("apply new slider", () => dho.Apply(prepareObject(new Slider { Position = new Vector2(256, 192), ComboIndex = 1, StartTime = dho.HitObject.StartTime, Path = new SliderPath(PathType.Bezier, new[] { Vector2.Zero, new Vector2(150, 100), new Vector2(300, 0), }), RepeatCount = 1 }))); }
public void TestChangeSamplesWithNoNodeSamples() { DrawableSlider slider = null; AddStep("create slider", () => { slider = (DrawableSlider)createSlider(repeats: 1); Add(slider); }); AddStep("change samples", () => slider.HitObject.Samples = new[] { new HitSampleInfo { Name = HitSampleInfo.HIT_CLAP }, new HitSampleInfo { Name = HitSampleInfo.HIT_WHISTLE }, }); AddAssert("head samples updated", () => assertSamples(((Slider)slider.HitObject).HeadCircle)); AddAssert("tick samples not updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType <SliderTick>().All(assertTickSamples)); AddAssert("repeat samples updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType <RepeatPoint>().All(assertSamples)); AddAssert("tail has no samples", () => ((Slider)slider.HitObject).TailCircle.Samples.Count == 0); bool assertTickSamples(SliderTick tick) => tick.Samples.Single().Name == "slidertick"; bool assertSamples(HitObject hitObject) { return(hitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP) && hitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_WHISTLE)); } }
public void TestBallTintChangedOnAccentChange() { DrawableSlider dho = null; AddStep("create slider", () => { var tintingSkin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo()); tintingSkin.Configuration.ConfigDictionary["AllowSliderBallTint"] = "1"; Child = new SkinProvidingContainer(tintingSkin) { RelativeSizeAxes = Axes.Both, Child = dho = new DrawableSlider(prepareObject(new Slider { Position = new Vector2(256, 192), IndexInCurrentCombo = 0, StartTime = Time.Current, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(150, 100), new Vector2(300, 0), }) })) }; }); AddStep("set accent white", () => dho.AccentColour.Value = Color4.White); AddAssert("ball is white", () => dho.ChildrenOfType <SliderBall>().Single().AccentColour == Color4.White); AddStep("set accent red", () => dho.AccentColour.Value = Color4.Red); AddAssert("ball is red", () => dho.ChildrenOfType <SliderBall>().Single().AccentColour == Color4.Red); }
public SliderCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) : base(slider) { this.position = position; InternalChild = CirclePiece = new HitCirclePiece(); Select(); }
public SliderSelectionBlueprint(DrawableSlider slider) : base(slider) { var sliderObject = (Slider)slider.HitObject; InternalChildren = new Drawable[] { new SliderBodyPiece(sliderObject), headBlueprint = new SliderCircleSelectionBlueprint(slider.HeadCircle, sliderObject, SliderPosition.Start), new SliderCircleSelectionBlueprint(slider.TailCircle, sliderObject, SliderPosition.End), new PathControlPointVisualiser(sliderObject), }; }
private SliderCircleMask(DrawableOsuHitObject hitObject, Vector2 position, DrawableSlider slider) : base(hitObject) { this.hitObject = hitObject; Origin = Anchor.Centre; Position = position; Size = slider.HeadCircle.Size; Scale = slider.HeadCircle.Scale; AddInternal(new RingPiece()); }
public SliderSelectionBlueprint(DrawableSlider slider) : base(slider) { var sliderObject = (Slider)slider.HitObject; InternalChildren = new Drawable[] { BodyPiece = new SliderBodyPiece(), HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start), TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End), ControlPointVisualiser = new PathControlPointVisualiser(sliderObject, true) }; }
public void TestChangeStackHeight() { DrawableSlider slider = null; AddStep("create slider", () => { slider = (DrawableSlider)createSlider(repeats: 1); Add(slider); }); AddStep("change stack height", () => slider.HitObject.StackHeight = 10); AddAssert("body positioned correctly", () => slider.Position == slider.HitObject.StackedPosition); }
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result) { hitPolicy.HandleHit(judgedObject); if (!judgedObject.DisplayResult || !DisplayJudgements.Value) { return; } judgementLayer.Add(poolDictionary[result.Type].Get(doj => doj.Apply(result, judgedObject))); if (judgedObject.HitObject.Kiai && result.Type != HitResult.Miss) { float angle = judgedObject switch { DrawableBeat b => b.HitObject.Angle, DrawableSlider s => s.HitObject.Nodes.Last().Angle, _ => 0 }; var isHardBeat = judgedObject is DrawableHardBeat; switch (effect.Value) { case KiaiType.Turbulent: for (int i = 0; i < (isHardBeat ? RNG.Next(60, 100) : RNG.Next(3, 9)); i++) { SliderParticleEmitter.AddParticle((isHardBeat ? RNG.NextSingle(0, 360) : angle), Inversed, result.Type); } break; case KiaiType.Classic: kiaiExplosionContainer.Add(new KiaiHitExplosion(colour.ForHitResult(judgedObject.Result.Type), judgedObject is DrawableHardBeat, Inversed, judgedObject is DrawableHardBeat ? 32 : 10) { Position = judgedObject is DrawableHardBeat ? Vector2.Zero : Extensions.GetCircularPosition(.5f, angle), Angle = angle, Anchor = Anchor.Centre, Origin = Anchor.Centre }); break; } } }
public SliderOverlay(DrawableSlider slider) : base(slider) { this.slider = slider; var obj = (Slider)slider.HitObject; InternalChildren = new Drawable[] { body = new SliderBody(obj) { AccentColour = Color4.Transparent, PathWidth = obj.Scale * 64 }, new SliderCircleOverlay(slider.HeadCircle, slider), new SliderCircleOverlay(slider.TailCircle, slider), }; }
public void TestAllSamplesStopDuringSeek() { DrawableSlider slider = null; PoolableSkinnableSample[] samples = null; ISamplePlaybackDisabler sampleDisabler = null; AddUntilStep("get variables", () => { sampleDisabler = Player; slider = Player.ChildrenOfType <DrawableSlider>().MinBy(s => s.HitObject.StartTime); samples = slider?.ChildrenOfType <PoolableSkinnableSample>().ToArray(); return(slider != null); }); AddUntilStep("wait for slider sliding then seek", () => { if (!slider.Tracking.Value) { return(false); } if (!samples.Any(s => s.Playing)) { return(false); } Player.ChildrenOfType <GameplayClockContainer>().First().Seek(40000); return(true); }); AddAssert("sample playback disabled", () => sampleDisabler.SamplePlaybackDisabled.Value); // because we are in frame stable context, it's quite likely that not all samples are "played" at this point. // the important thing is that at least one started, and that sample has since stopped. AddAssert("all looping samples stopped immediately", () => allStopped(allLoopingSounds)); AddUntilStep("all samples stopped eventually", () => allStopped(allSounds)); AddAssert("sample playback still disabled", () => sampleDisabler.SamplePlaybackDisabled.Value); AddUntilStep("seek finished, sample playback enabled", () => !sampleDisabler.SamplePlaybackDisabled.Value); AddUntilStep("any sample is playing", () => Player.ChildrenOfType <PausableSkinnableSound>().Any(s => s.IsPlaying)); }
public TestCaseSliderSelectionBlueprint() { var slider = new Slider { Position = new Vector2(256, 192), Path = new SliderPath(PathType.Bezier, new[] { Vector2.Zero, new Vector2(150, 150), new Vector2(300, 0) }) }; slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 }); Add(drawableObject = new DrawableSlider(slider)); }
public void TestChangeSamplesWithNoNodeSamples() { DrawableSlider slider = null; AddStep("create slider", () => { slider = (DrawableSlider)createSlider(repeats: 1); Add(slider); }); AddStep("change samples", () => slider.HitObject.Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_CLAP), new HitSampleInfo(HitSampleInfo.HIT_WHISTLE), }); AddAssert("head samples updated", () => assertSamples(slider.HitObject.HeadCircle)); AddAssert("tick samples not updated", () => slider.HitObject.NestedHitObjects.OfType <SliderTick>().All(assertTickSamples)); AddAssert("repeat samples updated", () => slider.HitObject.NestedHitObjects.OfType <SliderRepeat>().All(assertSamples)); AddAssert("tail has no samples", () => slider.HitObject.TailCircle.Samples.Count == 0);
public SliderMask(DrawableSlider slider) : base(slider) { this.slider = slider; Position = slider.Position; var sliderObject = (Slider)slider.HitObject; InternalChildren = new Drawable[] { body = new SliderBody(sliderObject) { AccentColour = Color4.Transparent, PathWidth = sliderObject.Scale * 64 }, new SliderCircleMask(slider.HeadCircle, slider), new SliderCircleMask(slider.TailCircle, slider), }; sliderObject.PositionChanged += _ => Position = slider.Position; }
public void Setup() => Schedule(() => { Clear(); slider = new Slider { Position = new Vector2(256, 192), Path = new SliderPath(PathType.Bezier, new[] { Vector2.Zero, new Vector2(150, 150), new Vector2(300, 0) }) }; slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 }); Add(drawableObject = new DrawableSlider(slider)); AddBlueprint(blueprint = new TestSliderBlueprint(drawableObject)); });
public SliderBall(Slider slider, DrawableSlider drawableSlider = null) { this.drawableSlider = drawableSlider; this.slider = slider; Blending = BlendingMode.Additive; Origin = Anchor.Centre; Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Children = new[] { FollowCircle = new FollowCircleContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both, Alpha = 0, Child = new SkinnableDrawable("Play/osu/sliderfollowcircle", _ => new DefaultFollowCircle()), }, new CircularContainer { Masking = true, RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = 1, Child = new Container { RelativeSizeAxes = Axes.Both, // TODO: support skin filename animation (sliderb0, sliderb1...) Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()), } } }; }
protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position);
protected override SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new TestSliderCircleBlueprint(slider, position);
public SliderCircleMask(DrawableSliderTail sliderTail, DrawableSlider slider) : this(sliderTail, ((Slider)slider.HitObject).Curve.PositionAt(1), slider) { }
private void retrieveDrawableSlider(int index) => AddStep($"retrieve {(index + 1).ToOrdinalWords()} slider", () => slider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.ElementAt(index));
private void applySliderState(DrawableSlider slider) { ((PlaySliderBody)slider.Body.Drawable).AccentColour = slider.AccentColour.Value.Opacity(0); ((PlaySliderBody)slider.Body.Drawable).BorderColour = slider.AccentColour.Value; }
public TestSliderCircleBlueprint(DrawableSlider slider, SliderPosition position) : base(slider, position) { }
public TestSliderBlueprint(DrawableSlider slider) : base(slider) { }