上次我介绍了在MonoGame/XNA中使用键盘, 这次我来介绍一下在MonoGame/XNA中使用触摸(触控)

通常在编写手机平板游戏用的最多的就是触摸(触控),所以你需要一台支持触摸的设备,比如手机/平板或者一台能够触摸的电脑显示器,当然使用模拟器也可以的。

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

image

【MonoGame】,项目模板有多种选择,你可以选【MonoGame Windows 10 Universal(Core Application)Project】【MonoGame Windows 10 Universal (XAML)Project】【MonoGame Android Project】【MonoGame iOS Project】,这些项目都支持触摸(触控)API,为了方便起见我们选择【MonoGame Windows 10 Universal (XAML)Project】,这种项目模板可以直接在Windows10上测试和调试,将项目名称命名为【MyTouchPanel】,点击【确定】

image

目标版本默认即可,最低版本选择【Windows 10 (10.0;版本10240)】这样保证支持所有Windows10用户。点击【确定】
image

在解决方案管理器中打开Game1.cs

image

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

 var touches = Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetState();
            foreach (var touch in touches)
            {
                if (touch.State != Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Released)
                {
                    System.Diagnostics.Debug.WriteLine(touch.State.ToString());
                }

            }

和之前介绍的手柄/键盘使用方式非常相似,不同的是获取到的触控状态是一个集合,需要用一个foreach循环去获取装当前状态。

Microsoft.Xna.Framework.Input.Touch.TouchLocationState有四种状态:无法识别(未知),手指触屏后移动,手指点击屏幕,手指点击屏幕后离开屏幕

image

上面的代码我并没有使用【touch.State == Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Pressed】来判断是否触屏,而是用了非Released来判断,这是因为触摸会同时执行pressed,moved,moved甚至会执行多次,所以非Released包含了这些操作!配合手势操作可以做多点触控游戏

点击【本地计算机】运行游戏

image

用你的手指触摸蓝色窗口

image

在Visual Studio的输出窗口就会显示触摸状态的名称

image

如果你的屏幕不带触摸功能,触摸蓝色窗口在Visual Studio的输出窗口是不会显示触摸状态的!那么在不支持触摸屏幕的情况下有没有办法开发触摸功能呢?

答案是有的!

方法一:

将【本地计算机】改为【模拟器】,点击【模拟器】调试代码

image

这时候会启动一个当前电脑的触摸屏模拟器,点击用鼠标蓝色屏幕即可!

image

也可以选择右边的工具栏来中的【手型】后点击蓝色窗口!

image

方法二(本方法可以方便的移植Windows游戏到触屏设备):

打开Game1.cs, 在Game1类的构造方法中加入

  IsMouseVisible = true;
            
  Microsoft.Xna.Framework.Input.Touch.TouchPanel.EnableMouseTouchPoint = true;

【IsMouseVisible = true; 】鼠标移动到蓝色窗口内显示【Microsoft.Xna.Framework.Input.Touch.TouchPanel.EnableMouseTouchPoint = true;】同时支持鼠标操作和触摸操作这样就可以用鼠标来代替触摸(触控操作)

注意:如果你使用的是XNA,那么只有XNA的windows phone项目才支持触摸(触控)API

如果你新建的是Android和iOS项目,无论是模拟器还是插入手机都可以测试上述代码!

完整代码如下:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace MyTouchPanel
{
    /// <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";
            IsMouseVisible = true;
            Microsoft.Xna.Framework.Input.Touch.TouchPanel.EnableMouseTouchPoint = true;
           
        }

        /// <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
            var touches = Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetState();
            foreach (var touch in touches)
            {
                if (touch.State != Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Released)
                {
                    System.Diagnostics.Debug.WriteLine(touch.State.ToString());
                }

            }
            
            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);
        }
    }
}