上一篇我介绍了在MonoGame/XNA中触控(触摸)操作,今天这一篇是对触控(触摸)的补充——手势(用手指单击,用手指双击,用手指拖拽,双手指捏合,双手指放大,用手指轻弹,用手指常按等)。

打开Visual Studio,【文件】【新建】【项目】

image

【MonoGame】【MonoGame Windows 10 Universal(XAML)Project】,项目名称命名为【MyTouchPanelGesture】,点击【确定】

【MonoGame Windows 10 Universal(XAML)Project】提供的Windows10模拟器可以很好的测试手势操作,你也可以选择【MonoGame Android Project】【MonoGame iOS Project】只要你有一台带触摸的设备这些都不问题。

image

为了支持windows10所有用户,最低版本选择【Windows 10 (10.0;版本10240)】,点击【确定】

image

打开解决方案管理器中的Game1.cs文件

image

在Update(GameTime gameTime)方法中加入以下代码:

while (Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable)//循环判断手势操作是否可用
            {
                var gesture = Microsoft.Xna.Framework.Input.Touch.TouchPanel.ReadGesture();//获取当前手势操作
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.DoubleTap)//判读该手势的类型是否双击
                {
                    System.Diagnostics.Debug.WriteLine("DoubleTap");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.DragComplete)//判读该手势的类型是否拖拽结束
                {
                    System.Diagnostics.Debug.WriteLine("DragComplete");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Flick)//判读该手势的类型是否轻弹
                {
                    System.Diagnostics.Debug.WriteLine("Flick");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.FreeDrag)//判读该手势的类型是否自由拖动
                {
                    System.Diagnostics.Debug.WriteLine("FreeDrag");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Hold)//判读该手势的类型是否长按
                {
                    System.Diagnostics.Debug.WriteLine("Hold");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.HorizontalDrag)//判读该手势的类型是否左右滑动(拖动)
                {
                    System.Diagnostics.Debug.WriteLine("HorizontalDrag");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.None)//无手势
                {
                    System.Diagnostics.Debug.WriteLine("None");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Pinch)//判读该手势的类型是否左右捏合
                {
                    System.Diagnostics.Debug.WriteLine("Pinch");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.PinchComplete)//判读该手势的类型是否捏合完成
                {
                    System.Diagnostics.Debug.WriteLine("PinchComplete");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Tap)//判读该手势的类型是否触摸(点击屏幕)
                {
                    System.Diagnostics.Debug.WriteLine("Tap");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.VerticalDrag)//判读该手势的类型是否上下滑动(拖动)
                {
                    System.Diagnostics.Debug.WriteLine("VerticalDrag");
                }
            }

将【本地计算机】改为【模拟器】,点击【模拟器】运行

image

选择模拟器右侧的手型,这时候你会发现,无论点击蓝色窗口的任何位置,输出窗口都没有任何输出信息,这表示上面输入的代码没有被执行!

image

手势操作和之前的触控(触摸)有点不同,在使用之前必须显式打开一个开关:找到Game1类的构造方法,在方法体内加入:

TouchPanel.EnabledGestures = GestureType.DoubleTap| GestureType.DragComplete| GestureType.Flick| GestureType.FreeDrag| GestureType.Hold| GestureType.HorizontalDrag| GestureType.None| GestureType.Pinch| GestureType.PinchComplete| GestureType.Tap| GestureType.VerticalDrag;

建议:加入使用到的手势,每种手势用【|】隔开即可!比如只用到长按屏幕Hold,只需要加入:

TouchPanel.EnabledGestures = GestureType.Hold;

由于带完整名称名称空间太长,可以在Game1.cs顶部使用

using Microsoft.Xna.Framework.Input.Touch;

省略完整路径的写法。

点击【模拟器】运行

点击

左右滑动

上下滑动

双手指捏合

注:模拟器无法测试手指放大手势操作,这里还是建议用真机来开发游戏。可以用windows10平板

完整代码如下:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace MyTouchPanelGesture
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            TouchPanel.EnabledGestures = GestureType.DoubleTap | GestureType.DragComplete | GestureType.Flick | GestureType.FreeDrag | GestureType.Hold | GestureType.HorizontalDrag | GestureType.None | GestureType.Pinch | GestureType.PinchComplete | GestureType.Tap | GestureType.VerticalDrag;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // TODO: Add your update logic here
            while (Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable)
            {
                var gesture = Microsoft.Xna.Framework.Input.Touch.TouchPanel.ReadGesture();
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.DoubleTap)
                {
                    System.Diagnostics.Debug.WriteLine("DoubleTap");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.DragComplete)
                {
                    System.Diagnostics.Debug.WriteLine("DragComplete");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Flick)
                {
                    System.Diagnostics.Debug.WriteLine("Flick");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.FreeDrag)
                {
                    System.Diagnostics.Debug.WriteLine("FreeDrag");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Hold)
                {
                    System.Diagnostics.Debug.WriteLine("Hold");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.HorizontalDrag)
                {
                    System.Diagnostics.Debug.WriteLine("HorizontalDrag");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.None)
                {
                    System.Diagnostics.Debug.WriteLine("None");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Pinch)
                {
                    System.Diagnostics.Debug.WriteLine("Pinch");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.PinchComplete)
                {
                    System.Diagnostics.Debug.WriteLine("PinchComplete");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.Tap)
                {
                    System.Diagnostics.Debug.WriteLine("Tap");
                }
                if (gesture.GestureType == Microsoft.Xna.Framework.Input.Touch.GestureType.VerticalDrag)
                {
                    System.Diagnostics.Debug.WriteLine("VerticalDrag");
                }
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}