public override bool Update(GameTime gameTime, TouchCollection currentTouch, out TouchStateBase nextState)
        {
            if (currentTouch.Count != 2)
            {
                TouchStateMachine.SubmitGestureEvent(new TwoFingeredDragEventArgs(GestureTiming.Completed, new Vector2()));
                nextState = new CooldownState();
                return(true);
            }

            if (currentTouch[0].TryGetPreviousLocation(out var prevFinger1) &&
                currentTouch[1].TryGetPreviousLocation(out var prevFinger2))
            {
                nextState = null;
                if (!Vector2.Normalize(prevFinger1.Position - currentTouch[0].Position)
                    .MovingInSameDirection(Vector2.Normalize(prevFinger2.Position - currentTouch[1].Position)))
                {
                    TouchStateMachine.SubmitGestureEvent(new TwoFingeredDragEventArgs(GestureTiming.Completed, new Vector2()));
                    nextState = new RotateAndScaleState();
                    return(true);
                }
            }

            var midpoint = Vector2.Lerp(currentTouch[0].Position, currentTouch[1].Position, 0);

            TouchStateMachine.SubmitGestureEvent(new TwoFingeredDragEventArgs(GestureTiming.InProgress, midpoint));

            nextState = null;
            return(false);
        }
示例#2
0
        /// <summary>
        /// Updates the current machine state
        /// </summary>
        /// <param name="gameTime">The game time.</param>
        /// <param name="currentTouch">The current touch.</param>
        /// <param name="nextState">The next state in the state machine.</param>
        /// <returns>
        /// A value indicating whether or not the state machine should advance to the next state
        /// </returns>
        public override bool Update(GameTime gameTime, TouchCollection currentTouch, out TouchStateBase nextState)
        {
            this.delayTimer += gameTime.ElapsedGameTime.Milliseconds;

            if (this.delayTimer > TouchStateMachine.Configuration.TapDelay)
            {
                TouchStateMachine.SubmitGestureEvent(new TapEventArgs(this.TapLocation, GestureTiming.Completed));
                nextState = new CooldownState();
                return(true);
            }

            var touched = currentTouch.Any();

            if (!touched && this.fingerDown)
            {
                // TODO: detect if taps are far apart and start a new tap
                nextState = new CooldownState();
                TouchStateMachine.SubmitGestureEvent(new DoubleTapEventArgs(this.TapLocation));
                return(true);
            }

            if (touched)
            {
                this.fingerDown = true;
            }

            nextState = null;
            return(false);
        }
        public override bool Update(GameTime gameTime, TouchCollection currentTouch, out TouchStateBase nextState)
        {
            if (currentTouch.Count != 1)
            {
                nextState = new CooldownState();
                TouchStateMachine.SubmitGestureEvent(new DragEventArgs(GestureTiming.Completed, new Vector2()));
                return(true);
            }

            TouchStateMachine.SubmitGestureEvent(new DragEventArgs(GestureTiming.InProgress, currentTouch.First().Position));
            nextState = null;
            return(false);
        }
        /// <summary>
        /// Updates the current machine state
        /// </summary>
        /// <param name="gameTime">The game time.</param>
        /// <param name="currentTouch">The current touch.</param>
        /// <param name="nextState">The next state in the state machine.</param>
        /// <returns>
        /// A value indicating whether or not the state machine should advance to the next state
        /// </returns>
        public override bool Update(GameTime gameTime, TouchCollection currentTouch, out TouchStateBase nextState)
        {
            this.touchedTimer += gameTime.ElapsedGameTime.Milliseconds;

            if (this.touchedTimer > TouchStateMachine.Configuration.TouchDelay || currentTouch.Count > 1)
            {
                nextState = new GestureActiveState();
                return(true);
            }

            if (currentTouch.Any())
            {
                if (currentTouch.Count == 1)
                {
                    var prevFirst = this.previousTouch[0].Position;
                    var currFirst = currentTouch[0].Position;

                    var direction = Vector2.Normalize(currFirst - prevFirst);
                    var distance  = Vector2.Distance(currFirst, prevFirst);

                    if (distance > TouchStateMachine.Configuration.FlickDistance)
                    {
                        TouchStateMachine.SubmitGestureEvent(new FlickEventArgs(prevFirst, direction, distance));
                        nextState = new CooldownState();
                        return(true);
                    }
                }

                this.previousTouch = currentTouch;
                nextState          = null;
                return(false);
            }

            TouchStateMachine.SubmitGestureEvent(new TapEventArgs(this.previousTouch[0].Position, GestureTiming.Started));
            nextState = new TappedState(this.previousTouch[0].Position);
            return(true);
        }
        public override bool Update(GameTime gameTime, TouchCollection currentTouch, out TouchStateBase nextState)
        {
            if (currentTouch.Count != 2)
            {
                TouchStateMachine.SubmitGestureEvent(new RotateAndScaleEventArgs(GestureTiming.Completed, 0, 0));
                nextState = new CooldownState();
                return(true);
            }

            if (!currentTouch[0].TryGetPreviousLocation(out var prevFinger1) ||
                !currentTouch[1].TryGetPreviousLocation(out var prevFinger2))
            {
                nextState = null;
                return(false);
            }

            if (Vector2.Normalize(prevFinger1.Position - currentTouch[0].Position)
                .MovingInSameDirection(Vector2.Normalize(prevFinger2.Position - currentTouch[1].Position)))
            {
                var pos = Vector2.Lerp(currentTouch[0].Position, currentTouch[1].Position, 0);
                TouchStateMachine.SubmitGestureEvent(new TwoFingeredDragEventArgs(GestureTiming.Started, pos));
                nextState = new TwoFingeredDragState();
                return(true);
            }

            var currZoom = Vector2.Distance(currentTouch[0].Position, currentTouch[1].Position);
            var prevZoom = Vector2.Distance(prevFinger1.Position, prevFinger2.Position);

            var currAngle = (currentTouch[0].Position - currentTouch[1].Position).GetAngleDegrees();
            var prevAngle = (prevFinger1.Position - prevFinger2.Position).GetAngleDegrees();

            var diff = currAngle - prevAngle;

            // Round tiny numbers to zero to stop drift
            if (Math.Abs(diff) < .3)
            {
                diff = 0;
            }

            // Handle very large or very small rotation amounts caused by gimbal locks
            else if (diff > 340)
            {
                diff = 360 - diff;
            }
            else if (diff < -340)
            {
                diff = -(360 + diff);
            }

            var zoom = currZoom - prevZoom;

            // Round tiny numbers to zero to stop drift
            if (Math.Abs(zoom) < 1)
            {
                zoom = 0;
            }

            TouchStateMachine.SubmitGestureEvent(new RotateAndScaleEventArgs(GestureTiming.InProgress, zoom, diff));

            nextState = null;
            return(false);
        }