예제 #1
0
파일: Catcher.cs 프로젝트: uyitroa/osu
        public void Add(DrawableHitObject fruit, Vector2 absolutePosition)
        {
            fruit.RelativePositionAxes = Axes.None;
            fruit.Position             = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0);

            fruit.Anchor      = Anchor.TopCentre;
            fruit.Origin      = Anchor.BottomCentre;
            fruit.Scale      *= 0.7f;
            fruit.LifetimeEnd = double.MaxValue;

            float distance = fruit.DrawSize.X / 2 * fruit.Scale.X;

            while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance))
            {
                fruit.X += RNG.Next(-5, 5);
                fruit.Y -= RNG.Next(0, 5);
            }

            caughtFruit.Add(fruit);

            if (((CatchBaseHit)fruit.HitObject).LastInCombo)
            {
                explode();
            }
        }
예제 #2
0
        /// <summary>
        /// Determines which drawable should currently receive a tooltip, taking into account
        /// <see cref="AppearDelay"/> and <see cref="AppearRadius"/>. Returns null if no valid
        /// target is found.
        /// </summary>
        /// <returns>The tooltip target. null if no valid one is found.</returns>
        private IHasTooltip findTooltipTarget()
        {
            // While we are dragging a tooltipped drawable we should show a tooltip for it.
            IHasTooltip draggedTarget = inputManager.DraggedDrawable as IHasTooltip;

            if (draggedTarget != null)
            {
                return(hasValidTooltip(draggedTarget) ? draggedTarget : null);
            }

            // Always keep 10 positions at equally-sized time intervals that add up to AppearDelay.
            double positionRecordInterval = AppearDelay / 10;

            if (Time.Current - lastRecordedPositionTime >= positionRecordInterval)
            {
                lastRecordedPositionTime = Time.Current;
                recentMousePositions.Add(new TimedPosition
                {
                    Time     = Time.Current,
                    Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position)
                });
            }

            recentMousePositions.RemoveAll(t => Time.Current - t.Time > AppearDelay);

            // For determining whether to show a tooltip we first select only those positions
            // which happened within a shorter, alpha-adjusted appear delay.
            double alphaModifiedAppearDelay = (1 - currentTooltip.Alpha) * AppearDelay;
            var    relevantPositions        = recentMousePositions.Where(t => Time.Current - t.Time <= alphaModifiedAppearDelay);

            // We then check whether all relevant positions fall within a radius of AppearRadius within the
            // first relevant position. If so, then the mouse has stayed within a small circular region of
            // AppearRadius for the duration of the modified appear delay, and we therefore want to display
            // the tooltip.
            Vector2 first          = relevantPositions.FirstOrDefault().Position;
            float   appearRadiusSq = AppearRadius * AppearRadius;

            if (relevantPositions.All(t => Vector2Extensions.DistanceSquared(t.Position, first) < appearRadiusSq))
            {
                // Only return the target if it has a valid tooltip
                IHasTooltip target = FindTarget();
                if (hasValidTooltip(target))
                {
                    return(target);
                }
            }

            return(null);
        }
예제 #3
0
        private ITooltipContentProvider handlePotentialTarget(ITooltipContentProvider targetCandidate)
        {
            // this method is intentionally split out from the main lookup above as it has several expensive delegate (LINQ) allocations.
            // this allows the case where no tooltip is displayed to run with no allocations.
            // further optimisation work can be done here to reduce allocations while a tooltip is being displayed.

            double appearDelay = (targetCandidate as IHasAppearDelay)?.AppearDelay ?? AppearDelay;
            // Always keep 10 positions at equally-sized time intervals that add up to AppearDelay.
            double positionRecordInterval = appearDelay / 10;

            if (Time.Current - lastRecordedPositionTime >= positionRecordInterval)
            {
                lastRecordedPositionTime = Time.Current;
                recentMousePositions.Add(new TimedPosition
                {
                    Time     = Time.Current,
                    Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position)
                });
            }

            // check that we have recorded enough positions to make a judgement about whether or not the cursor has been standing still for the required amount of time.
            // we can skip this if the appear-delay is set to 0, since then tooltips can appear instantly and we don't need to wait to record enough positions.
            if (appearDelay > 0 && (recentMousePositions.Count == 0 || lastRecordedPositionTime - recentMousePositions[0].Time < appearDelay - positionRecordInterval))
            {
                return(null);
            }

            recentMousePositions.RemoveAll(t => Time.Current - t.Time > appearDelay);

            // For determining whether to show a tooltip we first select only those positions
            // which happened within a shorter, alpha-adjusted appear delay.
            double alphaModifiedAppearDelay = (1 - CurrentTooltip.Alpha) * appearDelay;
            var    relevantPositions        = recentMousePositions.Where(t => Time.Current - t.Time <= alphaModifiedAppearDelay);

            // We then check whether all relevant positions fall within a radius of AppearRadius within the
            // first relevant position. If so, then the mouse has stayed within a small circular region of
            // AppearRadius for the duration of the modified appear delay, and we therefore want to display
            // the tooltip.
            Vector2 first          = relevantPositions.FirstOrDefault().Position;
            float   appearRadiusSq = AppearRadius * AppearRadius;

            if (relevantPositions.All(t => Vector2Extensions.DistanceSquared(t.Position, first) < appearRadiusSq))
            {
                return(targetCandidate);
            }

            return(null);
        }
예제 #4
0
            public void Add(DrawableHitObject fruit)
            {
                float distance = fruit.DrawSize.X / 2 * fruit.Scale.X;

                while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance))
                {
                    fruit.X += RNG.Next(-5, 5);
                    fruit.Y -= RNG.Next(0, 5);
                }

                caughtFruit.Add(fruit);

                if (((CatchHitObject)fruit.HitObject).LastInCombo)
                {
                    explode();
                }
            }
예제 #5
0
            public void AddToStack(DrawableHitObject fruit, Vector2 absolutePosition)
            {
                fruit.RelativePositionAxes = Axes.None;
                fruit.Position             = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0);

                fruit.Anchor      = Anchor.TopCentre;
                fruit.Origin      = Anchor.BottomCentre;
                fruit.Scale      *= 0.7f;
                fruit.LifetimeEnd = double.MaxValue;

                float distance = fruit.DrawSize.X / 2 * fruit.Scale.X;

                while (Children.OfType <DrawableFruit>().Any(f => Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance))
                {
                    fruit.X += RNG.Next(-5, 5);
                    fruit.Y -= RNG.Next(0, 5);
                }

                Add(fruit);
            }
예제 #6
0
 /// <summary>
 /// Distance squared from an arbitrary point p to this line.
 /// </summary>
 public float DistanceSquaredToPoint(Vector2 p)
 {
     return(Vector2Extensions.DistanceSquared(p, ClosestPointTo(p)));
 }
예제 #7
0
        /// <summary>
        /// Determines which drawable should currently receive a tooltip, taking into account
        /// <see cref="AppearDelay"/> and <see cref="AppearRadius"/>. Returns null if no valid
        /// target is found.
        /// </summary>
        /// <returns>The tooltip target. null if no valid one is found.</returns>
        private IHasTooltip findTooltipTarget()
        {
            // While we are dragging a tooltipped drawable we should show a tooltip for it.
            if (inputManager.DraggedDrawable is IHasTooltip draggedTarget)
            {
                return(hasValidTooltip(draggedTarget) ? draggedTarget : null);
            }

            IHasTooltip targetCandidate = FindTargets().Find(t => t.TooltipText != null);

            // check this first - if we find no target candidate we still want to clear the recorded positions and update the lastCandidate.
            if (targetCandidate != lastCandidate)
            {
                recentMousePositions.Clear();
                lastCandidate = targetCandidate;
            }

            if (targetCandidate == null)
            {
                return(null);
            }

            double appearDelay = (targetCandidate as IHasAppearDelay)?.AppearDelay ?? AppearDelay;
            // Always keep 10 positions at equally-sized time intervals that add up to AppearDelay.
            double positionRecordInterval = appearDelay / 10;

            if (Time.Current - lastRecordedPositionTime >= positionRecordInterval)
            {
                lastRecordedPositionTime = Time.Current;
                recentMousePositions.Add(new TimedPosition
                {
                    Time     = Time.Current,
                    Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position)
                });
            }

            // check that we have recorded enough positions to make a judgement about whether or not the cursor has been standing still for the required amount of time.
            // we can skip this if the appear-delay is set to 0, since then tooltips can appear instantly and we don't need to wait to record enough positions.
            if (appearDelay > 0 && (recentMousePositions.Count == 0 || lastRecordedPositionTime - recentMousePositions[0].Time < appearDelay - positionRecordInterval))
            {
                return(null);
            }

            recentMousePositions.RemoveAll(t => Time.Current - t.Time > appearDelay);

            // For determining whether to show a tooltip we first select only those positions
            // which happened within a shorter, alpha-adjusted appear delay.
            double alphaModifiedAppearDelay = (1 - CurrentTooltip.Alpha) * appearDelay;
            var    relevantPositions        = recentMousePositions.Where(t => Time.Current - t.Time <= alphaModifiedAppearDelay);

            // We then check whether all relevant positions fall within a radius of AppearRadius within the
            // first relevant position. If so, then the mouse has stayed within a small circular region of
            // AppearRadius for the duration of the modified appear delay, and we therefore want to display
            // the tooltip.
            Vector2 first          = relevantPositions.FirstOrDefault().Position;
            float   appearRadiusSq = AppearRadius * AppearRadius;

            if (relevantPositions.All(t => Vector2Extensions.DistanceSquared(t.Position, first) < appearRadiusSq))
            {
                return(targetCandidate);
            }

            return(null);
        }