예제 #1
0
        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()),
                    }
                }
            };
        }
예제 #2
0
 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);
 }
예제 #3
0
        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);
        }
예제 #4
0
        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]);
                }
            });
        }
예제 #5
0
        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));
        }
예제 #7
0
        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));
        }
예제 #8
0
        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
            })));
        }
예제 #9
0
        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));
            }
        }
예제 #10
0
        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();
        }
예제 #12
0
        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),
            };
        }
예제 #13
0
        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());
        }
예제 #14
0
        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)
            };
        }
예제 #15
0
        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);
        }
예제 #16
0
        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;
                }
            }
        }
예제 #17
0
파일: SliderOverlay.cs 프로젝트: mc-nya/osu
        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));
        }
예제 #19
0
        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));
        }
예제 #20
0
        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);
예제 #21
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;
        }
예제 #22
0
        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));
        });
예제 #23
0
파일: SliderBall.cs 프로젝트: yansaan/osu
        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()),
                    }
                }
            };
        }
예제 #24
0
 protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position);
예제 #25
0
 protected override SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new TestSliderCircleBlueprint(slider, position);
예제 #26
0
 public SliderCircleMask(DrawableSliderTail sliderTail, DrawableSlider slider)
     : this(sliderTail, ((Slider)slider.HitObject).Curve.PositionAt(1), slider)
 {
 }
예제 #27
0
 private void retrieveDrawableSlider(int index) =>
 AddStep($"retrieve {(index + 1).ToOrdinalWords()} slider", () =>
         slider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.ElementAt(index));
예제 #28
0
 private void applySliderState(DrawableSlider slider)
 {
     ((PlaySliderBody)slider.Body.Drawable).AccentColour = slider.AccentColour.Value.Opacity(0);
     ((PlaySliderBody)slider.Body.Drawable).BorderColour = slider.AccentColour.Value;
 }
예제 #29
0
 public TestSliderCircleBlueprint(DrawableSlider slider, SliderPosition position)
     : base(slider, position)
 {
 }
예제 #30
0
 public TestSliderBlueprint(DrawableSlider slider)
     : base(slider)
 {
 }