C#开发跨平台游戏——在MONOGAME/XNA中使用触控操作TouchPanel
上次我介绍了在MonoGame/XNA中使用键盘, 这次我来介绍一下在MonoGame/XNA中使用触摸(触控)
通常在编写手机平板游戏用的最多的就是触摸(触控),所以你需要一台支持触摸的设备,比如手机/平板或者一台能够触摸的电脑显示器,当然使用模拟器也可以的。
打开Visual Studio,【文件】【新建】【项目】
【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】,点击【确定】
目标版本默认即可,最低版本选择【Windows 10 (10.0;版本10240)】这样保证支持所有Windows10用户。点击【确定】
在解决方案管理器中打开Game1.cs
找到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有四种状态:无法识别(未知),手指触屏后移动,手指点击屏幕,手指点击屏幕后离开屏幕
上面的代码我并没有使用【touch.State == Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Pressed】来判断是否触屏,而是用了非Released来判断,这是因为触摸会同时执行pressed,moved,moved甚至会执行多次,所以非Released包含了这些操作!配合手势操作可以做多点触控游戏
点击【本地计算机】运行游戏
用你的手指触摸蓝色窗口
在Visual Studio的输出窗口就会显示触摸状态的名称
如果你的屏幕不带触摸功能,触摸蓝色窗口在Visual Studio的输出窗口是不会显示触摸状态的!那么在不支持触摸屏幕的情况下有没有办法开发触摸功能呢?
答案是有的!
方法一:
将【本地计算机】改为【模拟器】,点击【模拟器】调试代码
这时候会启动一个当前电脑的触摸屏模拟器,点击用鼠标蓝色屏幕即可!
也可以选择右边的工具栏来中的【手型】后点击蓝色窗口!
方法二(本方法可以方便的移植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); } } }