示例#1
0
文件: MenuCursor.cs 项目: oscsan/osu
        protected override bool OnMouseMove(InputState state)
        {
            if (dragging)
            {
                Debug.Assert(state.Mouse.PositionMouseDown != null);

                // don't start rotating until we're moved a minimum distance away from the mouse down location,
                // else it can have an annoying effect.
                startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30;

                if (startRotation)
                {
                    Vector2 offset  = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
                    float   degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;

                    // Always rotate in the direction of least distance
                    float diff = (degrees - ActiveCursor.Rotation) % 360;
                    if (diff < -180)
                    {
                        diff += 360;
                    }
                    if (diff > 180)
                    {
                        diff -= 360;
                    }
                    degrees = ActiveCursor.Rotation + diff;

                    ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint);
                }
            }

            return(base.OnMouseMove(state));
        }
示例#2
0
        public virtual void HandleMousePositionChange(InputState state)
        {
            var mouse = state.Mouse;

            foreach (var h in InputHandlers)
            {
                if (h.Enabled && h is INeedsMousePositionFeedback handler)
                {
                    handler.FeedbackMousePositionChange(mouse.Position);
                }
            }

            handleMouseMove(state);

            if (!dragStarted)
            {
                if (mouse.IsPressed(MouseButton.Left) && Vector2Extensions.Distance(mouse.PositionMouseDown ?? mouse.Position, mouse.Position) > click_drag_distance)
                {
                    handleMouseDragStart(state);
                }
            }
            else
            {
                handleMouseDrag(state);
            }
        }
        private IEnumerable <Vector2> getPolygonAngles(float offset, int sides, int projectiles)
        {
            var angles = new List <Vector2>();
            var points = getPolygonPoints(sides).ToArray();

            var sideLen = Vector2Extensions.Distance(points[0], points[1]);
            var space   = sideLen / (int)(projectiles / sides);

            for (var i = 0; i < points.Length; i++)
            {
                var point     = points[i];
                var nextPoint = points[(i + 1) % points.Length];

                var angle = Math.Atan2(nextPoint.Y - point.Y, nextPoint.X - point.X);
                var xT    = Math.Cos(angle) * space;
                var yT    = Math.Sin(angle) * space;

                for (var j = 0; j < projectiles / sides; j++)
                {
                    var x = point.X + xT * j;
                    var y = point.Y + yT * j;

                    var xRot = x * Math.Cos(offset) - y * Math.Sin(offset);
                    var yRot = x * Math.Sin(offset) + y * Math.Cos(offset);

                    angles.Add(new Vector2((float)xRot, (float)yRot));
                }
            }

            return(angles);
        }
示例#4
0
        protected override bool OnClick(ClickEvent e)
        {
            var relativePos = (e.ScreenSpaceMouseDownPosition - ScreenSpaceDrawQuad.Centre) / SkeletonDrawScale;
            var distances   = Skeleton.Bones.Select(b => Vector2Extensions.Distance(b.Root2D, relativePos));
            var close       = Skeleton.Bones.Zip(distances, (bone, distance) => (bone, distance))
                              .Where(b => b.distance < MathF.Sqrt(2) * KinematicsDrawNode.BONE_NODE_SIZE)
                              .OrderBy(b => b.distance);

            if (close.Count() > 0)
            {
                BoneClicked?.Invoke(close.First().bone);
                return(true);
            }
            return(base.OnClick(e));
        }
示例#5
0
 public virtual void HandlePositionChange(InputState state, Vector2 lastPosition)
 {
     if (EnableDrag)
     {
         if (!DragStarted)
         {
             var mouse = state.Mouse;
             if (mouse.IsPressed(Button) && Vector2Extensions.Distance(MouseDownPosition ?? mouse.Position, mouse.Position) > ClickDragDistance)
             {
                 HandleMouseDragStart(state);
             }
         }
         else
         {
             HandleMouseDrag(state, lastPosition);
         }
     }
 }
示例#6
0
        private void applyStackingOld(Beatmap <OsuHitObject> beatmap)
        {
            for (int i = 0; i < beatmap.HitObjects.Count; i++)
            {
                OsuHitObject currHitObject = beatmap.HitObjects[i];

                if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
                {
                    continue;
                }

                double startTime   = currHitObject.GetEndTime();
                int    sliderStack = 0;

                for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
                {
                    double stackThreshold = beatmap.HitObjects[i].TimePreempt * beatmap.BeatmapInfo.StackLeniency;

                    if (beatmap.HitObjects[j].StartTime - stackThreshold > startTime)
                    {
                        break;
                    }

                    // The start position of the hitobject, or the position at the end of the path if the hitobject is a slider
                    Vector2 position2 = currHitObject is Slider currSlider
                        ? currSlider.Position + currSlider.Path.PositionAt(1)
                        : currHitObject.Position;

                    if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
                    {
                        currHitObject.StackHeight++;
                        startTime = beatmap.HitObjects[j].GetEndTime();
                    }
                    else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, position2) < stack_distance)
                    {
                        //Case for sliders - bump notes down and right, rather than up and left.
                        sliderStack++;
                        beatmap.HitObjects[j].StackHeight -= sliderStack;
                        startTime = beatmap.HitObjects[j].GetEndTime();
                    }
                }
            }
        }
示例#7
0
            /// <summary>
            /// Add a caught fruit to the catcher's stack.
            /// </summary>
            /// <param name="fruit">The fruit that was caught.</param>
            public void Add(DrawableHitObject fruit)
            {
                float ourRadius   = fruit.DrawSize.X / 2 * fruit.Scale.X;
                float theirRadius = 0;

                const float allowance = 6;

                while (caughtFruit.Any(f =>
                                       f.LifetimeEnd == double.MaxValue &&
                                       Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = f.DrawSize.X / 2 * f.Scale.X)) / (allowance / 2)))
                {
                    float diff = (ourRadius + theirRadius) / allowance;
                    fruit.X += (RNG.NextSingle() - 0.5f) * 2 * diff;
                    fruit.Y -= RNG.NextSingle() * diff;
                }

                fruit.X = MathHelper.Clamp(fruit.X, -CATCHER_SIZE / 2, CATCHER_SIZE / 2);

                caughtFruit.Add(fruit);
            }
示例#8
0
文件: MenuCursor.cs 项目: zivoy/osu
        protected override bool OnMouseMove(MouseMoveEvent e)
        {
            if (dragRotationState != DragRotationState.NotDragging)
            {
                var position = e.MousePosition;
                var distance = Vector2Extensions.Distance(position, positionMouseDown);

                // don't start rotating until we're moved a minimum distance away from the mouse down location,
                // else it can have an annoying effect.
                if (dragRotationState == DragRotationState.DragStarted && distance > 30)
                {
                    dragRotationState = DragRotationState.Rotating;
                }

                // don't rotate when distance is zero to avoid NaN
                if (dragRotationState == DragRotationState.Rotating && distance > 0)
                {
                    Vector2 offset  = e.MousePosition - positionMouseDown;
                    float   degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;

                    // Always rotate in the direction of least distance
                    float diff = (degrees - activeCursor.Rotation) % 360;
                    if (diff < -180)
                    {
                        diff += 360;
                    }
                    if (diff > 180)
                    {
                        diff -= 360;
                    }
                    degrees = activeCursor.Rotation + diff;

                    activeCursor.RotateTo(degrees, 600, Easing.OutQuint);
                }
            }

            return(base.OnMouseMove(e));
        }
示例#9
0
        private void applyStackingOld(Beatmap <OsuHitObject> beatmap)
        {
            for (int i = 0; i < beatmap.HitObjects.Count; i++)
            {
                OsuHitObject currHitObject = beatmap.HitObjects[i];

                if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
                {
                    continue;
                }

                double startTime   = (currHitObject as IHasEndTime)?.EndTime ?? currHitObject.StartTime;
                int    sliderStack = 0;

                for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
                {
                    double stackThreshold = beatmap.HitObjects[i].TimePreempt * beatmap.BeatmapInfo.StackLeniency;

                    if (beatmap.HitObjects[j].StartTime - stackThreshold > startTime)
                    {
                        break;
                    }

                    if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
                    {
                        currHitObject.StackHeight++;
                        startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime;
                    }
                    else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.EndPosition) < stack_distance)
                    {
                        //Case for sliders - bump notes down and right, rather than up and left.
                        sliderStack++;
                        beatmap.HitObjects[j].StackHeight -= sliderStack;
                        startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime;
                    }
                }
            }
        }
示例#10
0
        private void applyStacking(Beatmap <OsuHitObject> beatmap, int startIndex, int endIndex)
        {
            if (startIndex > endIndex)
            {
                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} cannot be greater than {nameof(endIndex)}.");
            }
            if (startIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} cannot be less than 0.");
            }
            if (endIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(endIndex), $"{nameof(endIndex)} cannot be less than 0.");
            }

            int extendedEndIndex = endIndex;

            if (endIndex < beatmap.HitObjects.Count - 1)
            {
                // Extend the end index to include objects they are stacked on
                for (int i = endIndex; i >= startIndex; i--)
                {
                    int stackBaseIndex = i;

                    for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
                    {
                        OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
                        if (stackBaseObject is Spinner)
                        {
                            break;
                        }

                        OsuHitObject objectN = beatmap.HitObjects[n];
                        if (objectN is Spinner)
                        {
                            continue;
                        }

                        double endTime        = stackBaseObject.GetEndTime();
                        double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;

                        if (objectN.StartTime - endTime > stackThreshold)
                        {
                            //We are no longer within stacking range of the next object.
                            break;
                        }

                        if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance ||
                            (stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance))
                        {
                            stackBaseIndex = n;

                            // HitObjects after the specified update range haven't been reset yet
                            objectN.StackHeight = 0;
                        }
                    }

                    if (stackBaseIndex > extendedEndIndex)
                    {
                        extendedEndIndex = stackBaseIndex;
                        if (extendedEndIndex == beatmap.HitObjects.Count - 1)
                        {
                            break;
                        }
                    }
                }
            }

            //Reverse pass for stack calculation.
            int extendedStartIndex = startIndex;

            for (int i = extendedEndIndex; i > startIndex; i--)
            {
                int n = i;

                /* We should check every note which has not yet got a stack.
                 * Consider the case we have two interwound stacks and this will make sense.
                 *
                 * o <-1      o <-2
                 *  o <-3      o <-4
                 *
                 * We first process starting from 4 and handle 2,
                 * then we come backwards on the i loop iteration until we reach 3 and handle 1.
                 * 2 and 1 will be ignored in the i loop because they already have a stack value.
                 */

                OsuHitObject objectI = beatmap.HitObjects[i];
                if (objectI.StackHeight != 0 || objectI is Spinner)
                {
                    continue;
                }

                double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency;

                /* If this object is a hitcircle, then we enter this "special" case.
                 * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
                 * Any other case is handled by the "is Slider" code below this.
                 */
                if (objectI is HitCircle)
                {
                    while (--n >= 0)
                    {
                        OsuHitObject objectN = beatmap.HitObjects[n];
                        if (objectN is Spinner)
                        {
                            continue;
                        }

                        double endTime = objectN.GetEndTime();

                        if (objectI.StartTime - endTime > stackThreshold)
                        {
                            //We are no longer within stacking range of the previous object.
                            break;
                        }

                        // HitObjects before the specified update range haven't been reset yet
                        if (n < extendedStartIndex)
                        {
                            objectN.StackHeight = 0;
                            extendedStartIndex  = n;
                        }

                        /* This is a special case where hticircles are moved DOWN and RIGHT (negative stacking) if they are under the *last* slider in a stacked pattern.
                         *    o==o <- slider is at original location
                         *        o <- hitCircle has stack of -1
                         *         o <- hitCircle has stack of -2
                         */
                        if (objectN is Slider && Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance)
                        {
                            int offset = objectI.StackHeight - objectN.StackHeight + 1;

                            for (int j = n + 1; j <= i; j++)
                            {
                                //For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
                                OsuHitObject objectJ = beatmap.HitObjects[j];
                                if (Vector2Extensions.Distance(objectN.EndPosition, objectJ.Position) < stack_distance)
                                {
                                    objectJ.StackHeight -= offset;
                                }
                            }

                            //We have hit a slider.  We should restart calculation using this as the new base.
                            //Breaking here will mean that the slider still has StackCount of 0, so will be handled in the i-outer-loop.
                            break;
                        }

                        if (Vector2Extensions.Distance(objectN.Position, objectI.Position) < stack_distance)
                        {
                            //Keep processing as if there are no sliders.  If we come across a slider, this gets cancelled out.
                            //NOTE: Sliders with start positions stacking are a special case that is also handled here.

                            objectN.StackHeight = objectI.StackHeight + 1;
                            objectI             = objectN;
                        }
                    }
                }
                else if (objectI is Slider)
                {
                    /* We have hit the first slider in a possible stack.
                     * From this point on, we ALWAYS stack positive regardless.
                     */
                    while (--n >= startIndex)
                    {
                        OsuHitObject objectN = beatmap.HitObjects[n];
                        if (objectN is Spinner)
                        {
                            continue;
                        }

                        if (objectI.StartTime - objectN.StartTime > stackThreshold)
                        {
                            //We are no longer within stacking range of the previous object.
                            break;
                        }

                        if (Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance)
                        {
                            objectN.StackHeight = objectI.StackHeight + 1;
                            objectI             = objectN;
                        }
                    }
                }
            }
        }
示例#11
0
 /// <summary>
 /// Distance from an arbitrary point to this line.
 /// </summary>
 public float DistanceToPoint(Vector2 p)
 {
     return(Vector2Extensions.Distance(p, ClosestPointTo(p)));
 }
示例#12
0
        private void updateMouseEvents(InputState state)
        {
            MouseState mouse = (MouseState)state.Mouse;

            var last = state.Last?.Mouse as MouseState;

            if (last == null)
            {
                return;
            }

            if (mouse.Position != last.Position)
            {
                handleMouseMove(state);
                if (isDragging)
                {
                    handleMouseDrag(state);
                }
            }

            for (MouseButton b = 0; b < MouseButton.LastButton; b++)
            {
                var lastPressed = last.IsPressed(b);

                if (lastPressed != mouse.IsPressed(b))
                {
                    if (lastPressed)
                    {
                        handleMouseUp(state, b);
                    }
                    else
                    {
                        handleMouseDown(state, b);
                    }
                }
            }

            if (mouse.WheelDelta != 0 && Host.Window.CursorInWindow)
            {
                handleWheel(state);
            }

            if (mouse.HasAnyButtonPressed)
            {
                if (!last.HasAnyButtonPressed)
                {
                    //stuff which only happens once after the mousedown state
                    mouse.PositionMouseDown = state.Mouse.Position;
                    LastActionTime          = Time.Current;

                    if (mouse.IsPressed(MouseButton.Left))
                    {
                        isValidClick = true;

                        if (Time.Current - lastClickTime < double_click_time)
                        {
                            if (handleMouseDoubleClick(state))
                            {
                                //when we handle a double-click we want to block a normal click from firing.
                                isValidClick = false;
                            }

                            lastClickTime = 0;
                        }
                        else
                        {
                            lastClickTime = Time.Current;
                        }
                    }
                }

                if (!isDragging && Vector2Extensions.Distance(mouse.PositionMouseDown ?? mouse.Position, mouse.Position) > drag_start_distance)
                {
                    isDragging = true;
                    handleMouseDragStart(state);
                }
            }
            else if (last.HasAnyButtonPressed)
            {
                if (isValidClick && (DraggedDrawable == null || Vector2Extensions.Distance(mouse.PositionMouseDown ?? mouse.Position, mouse.Position) < click_drag_distance))
                {
                    handleMouseClick(state);
                }

                mouseDownInputQueue     = null;
                mouse.PositionMouseDown = null;
                isValidClick            = false;

                if (isDragging)
                {
                    isDragging = false;
                    handleMouseDragEnd(state);
                }
            }
        }