Beispiel #1
0
        private void createTicks()
        {
            if (TickDistance == 0)
            {
                return;
            }

            var length         = Curve.Distance;
            var tickDistance   = Math.Min(TickDistance, length);
            var repeatDuration = length / Velocity;

            var minDistanceFromEnd = Velocity * 0.01;

            AddNested(new Fruit
            {
                Samples     = Samples,
                ComboColour = ComboColour,
                StartTime   = StartTime,
                X           = X
            });

            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 timeProgress     = d / length;
                    var distanceProgress = reversed ? 1 - timeProgress : timeProgress;

                    var lastTickTime = repeatStartTime + timeProgress * repeatDuration;
                    AddNested(new Droplet
                    {
                        StartTime   = lastTickTime,
                        ComboColour = ComboColour,
                        X           = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
                        Samples     = new List <SampleInfo>(Samples.Select(s => new SampleInfo
                        {
                            Bank   = s.Bank,
                            Name   = @"slidertick",
                            Volume = s.Volume
                        }))
                    });
                }

                double tinyTickInterval = tickDistance / length * repeatDuration;
                while (tinyTickInterval > 100)
                {
                    tinyTickInterval /= 2;
                }

                for (double t = 0; t < repeatDuration; t += tinyTickInterval)
                {
                    double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration;

                    AddNested(new TinyDroplet
                    {
                        StartTime   = repeatStartTime + t,
                        ComboColour = ComboColour,
                        X           = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
                        Samples     = new List <SampleInfo>(Samples.Select(s => new SampleInfo
                        {
                            Bank   = s.Bank,
                            Name   = @"slidertick",
                            Volume = s.Volume
                        }))
                    });
                }

                AddNested(new Fruit
                {
                    Samples     = Samples,
                    ComboColour = ComboColour,
                    StartTime   = repeatStartTime + repeatDuration,
                    X           = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
                });
            }
        }
Beispiel #2
0
 public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
        protected override IEnumerable <CytusHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
        {
            if (!(original is IHasXPosition))
            {
                throw new Exception($"This hitobject of type {original.GetType().Name} is not a {nameof(IHasXPosition)}!");
            }

            double time = original.StartTime;
            float  x    = ((IHasXPosition)original).X;
            float  y    = beatmap.GetScanPosition(original.StartTime, Constants.BeatsPerScan);

            // we have to determine if this is a slider or normal hitobject
            // TODO: check for IHasRepeats
            if (original is IHasCurve ihc)
            {
                CytusSliderTick lastTick;
                double          endTime      = ihc.EndTime;
                var             tp           = beatmap.ControlPointInfo.TimingPointAt(time);
                double          tickInterval = tp.BeatLength / (int)tp.TimeSignature;
                SliderCurve     curve        = ihc.Curve ?? new SliderCurve {
                    ControlPoints = ihc.ControlPoints,
                    CurveType     = ihc.CurveType,
                    Distance      = ihc.Distance,
                    Offset        = Vector2.Zero
                };

                var end = lastTick = new CytusSliderEnd(endTime, x + curve.PositionAt(1).X, beatmap.GetScanPosition(endTime, Constants.BeatsPerScan))
                {
                    Samples            = original.Samples,
                    SampleControlPoint = original.SampleControlPoint
                };

                var ticks = new List <CytusSliderTick>();
                for (double i = endTime - tickInterval; i >= time + tickInterval / 2; i -= tickInterval)
                {
                    ticks.Add(lastTick = new CytusSliderTick(i, x + curve.PositionAt((i - time) / (endTime - time)).X, beatmap.GetScanPosition(i, Constants.BeatsPerScan), lastTick)
                    {
                        Samples            = original.Samples,
                        SampleControlPoint = original.SampleControlPoint
                    });
                }

                var start = new CytusSliderHead(original.StartTime, x, y, lastTick)
                {
                    Samples            = original.Samples,
                    SampleControlPoint = original.SampleControlPoint
                };

                yield return(start);

                foreach (var tick in ticks)
                {
                    yield return(tick);
                }
                yield return(end);
            }
            else
            {
                // This is a normal note
                yield return(new CytusNote(time, x, y)
                {
                    Samples = original.Samples,
                    SampleControlPoint = original.SampleControlPoint
                });
            }
        }