




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘要上一回我们为大家介绍了更多的 XNA Framework 支持游戏开发的类别,包括支持输入控制,音效播放,以及背景音乐播放控制的类别等等,让读者能够为所制作的游戏程序加入更丰富的游戏效果。这一回我们将要为大家介绍进阶的输入控制技巧,让使用者可以利用 Windows Phone 7 智能型手机支持多点触控的触控屏幕控制游戏程序的执行。 认识手势操作在上一回的介绍中,我们学会如何利用 TouchPanel 类别的 GetState 方法查询智能型手机的触摸屏的状态,并依据使用者触碰在触控屏幕的位置移动游戏程序显示的图形的位置。呼叫 TouchPanel 类别的 GetState 方法查询触控屏幕的状态并判断用户触碰触控屏幕的位置只是最简单的触控屏幕控制技巧,除了支持取得触控屏幕的状态以外,触控屏幕还支持用户进行多种不同的控制,包括触碰、触碰不放、水平拖曳、垂直拖曳、自由拖曳、以及轻拂等操作。表1 所示即为触控屏幕的各种状态的说明:表1:触控屏幕的各种状态的说明操作动作说明Tap触碰。触碰触控屏幕后放开,没有移动的动作。DoubleTap连续触碰。连续触碰同一个位置两次。Hold点住不放。触碰后不放达一段时间。VerticalDrag垂直拖曳。触碰屏幕后上下移动。HorizontalDrag水平拖曳。触碰屏幕后左右移动。FreeDrag自由拖曳。触碰屏幕后往任意方向移动DragComplete拖曳结束。Flick轻拂。触碰屏幕后往任意方向拂动后离开屏幕。Pinch同时便用两个手指头触碰触控屏幕后移动。PinchCompletePinch 操作结束。 以 XNA 为基础的游戏程序可以利用表1所列的各种触控屏幕状态判断用户执行的触控操作种类,以反应使用者的触控操作。注意以 XNA 为基础的游戏程序必须启用触控功能才能够让游戏的使用者进行触控操作,如果已启用 Pinch 操作功能,则当用户利用两个手指头同时触碰触控屏幕并进行移动时,就会产生 Pinch 操作,而不是两个不同的拖曳操作,如果未启用 Pinch 操作功能,则所产生的就不是 Pinch 操作,而是依据两个触碰位置的平均为准的单一拖曳操作。 启用手势操作支持以 XNA 为基础的游戏程序必须设定 TouchPanel 类别的 EnabledGestures 属性,才能够启用手势操作功能,以支持用户以手势操作游戏程序。程序设计师可以在 Game1 类别的 Initialize 方法执行设定 TouchPanel 类别的 EnabledGestures 属性的动作,以启用手势操作支持,做法如下:TouchPanel.EnabledGestures = GestureType.Hold | GestureType.Tap | GestureType.DoubleTap | GestureType.FreeDrag | GestureType.Flick | GestureType.Pinch;说明请注意在上述的程序中,GestureType.FreeDrag 设定表示要支持使用者以自由拖曳的方式操作游戏程序,设定了 GestureType.FreeDrag 就已经涵盖 GestureType.VerticalDrag 设定和 GestureType.HorizontalDrag 设定。而 DragComplete 状态和 PinchComplete 状态代表触控动作结束的状态,不需要启用。注意以 XNA 为基础的游戏程序可以视需要启用需要使用的触控功能,例如只支持用户利用触控的方式选取菜单的游戏程序,就可以仅启用 Tap 和 VerticalDrag 两种触控功能,让用户以垂直拖曳的方式卷动游戏程序提供的菜单,再触碰欲选择的菜单,其他不需要用到的触控控制功能就不需要启用,避免启用多种触控操作功能,造成判断触控操作动作的逻辑复杂,进而影响到触控的精确度和游戏程序执行的效能。 处理使用者的手势操作启用了手势操作功能之后,以 XNA 为基础的应用程序可以在 Game1 类别的 Update 方法中呼叫 TouchPanel 类别的 ReadGesture 方法取得用户的手势操作信息。请注意读取使用者的手势操作的做法和呼叫 TouchPanel 类别的 GetState 方法读取触控面板的状态的做法不同,因为用户对游戏程序的触控操作会产生多个手势信息,来不及被游戏处理的手势信息会被存放到队列中等待处理,让游戏程序利用循环取出并加以处理。以下的 Update 方法便会利用 while 循环,搭配 TouchPanel 类别的 IsGestureAvailable 属性判断是否还有用户触控操作产生的手势信息尚未被处理,如果尚有使用者触控操作产生的手势信息尚未被处理,则呼叫 TouchPanel 类别的 ReadGesture 方法读取手势信息,并加以处理: protected override void Update(GameTime gameTime) while (TouchPanel.IsGestureAvailable) /判斷是否尚有手勢資訊尚未被處理 GestureSample gesture = TouchPanel.ReadGesture(); /讀取尚未處理的手勢資訊 switch (gesture.GestureType) /判斷手勢操作的種類 case GestureType.Tap: /如果手勢操作的種類是Tap /處理 Tap 操作 break; 因为 GestureType.FreeDrag 自由拖曳操作已经包括 GestureType.VerticalDrag 垂直拖曳操作和 GestureType.HorizontalDrag 水平拖曳操作,所以游戏程序在判断用户的触控操作的动作时,不需要既判断动作是否为 GestureType.FreeDrag,又判断动作是否为 GestureType.VerticalDrag 或 GestureType.HorizontalDrag,两者择一处理即可。特别注意使用 TouchPanel 类别进行触控控制的游戏程序可以呼叫 TouchPanel 类别的 GetState 方法取得使用者对触控面板的触控状态,或是呼叫 TouchPanel 类别的 ReadGesture 方法取得使用者的手势操作状态,不要两者混用,否则将会无法得到正确的结果。例如先利用 TouchPanel 类别的 ReadGesture 方法取得使用者的手势操作状态,再利用 TouchPanel 类别的 GetState 方法取得用户触碰屏幕的位置,当做手势操作触碰屏幕的位置来使用就是错误的做法。请注意呼叫 TouchPanel 类别的 ReadGesture 方法读取手势信息时,读取到的手势信息会以 GestureSample 结构的型式传回给呼叫者。表2 所示为 GestureSample 结构常用的属性:表2:GestureSample 结构常用的属性属性名称说明Delta存放与第一个碰触点的偏差量。Delta2存放与第二个碰触点的偏差量。GestureType存放触控操作的种类。Position存放第一个碰触点的位置。Position2存放第二个碰触点的位置。Timestamp存放触控操作发生的时间。 因为呼叫 TouchPanel 类别的 ReadGesture 方法传回的 GestureSample 结构只能存放第一个和第二触碰点的位置:Position 和 Postition2,以及存放两个触碰点的偏差量,所以只能支持到最多两个手指头的操作,事实上 Windows Phone 7 配备的触控屏幕最多可以支持到多达四个触碰点的触控操作,程序可以经由呼叫 TouchPanel 类别的 GetCapabilities 方法查询触控屏幕的基本功能,取得 TouchPanelCapabilities 结构型态的传回值之后,就可以利用 TouchPanelCapabilities 结构的 MaximumTouchCount 成员得知触控屏幕最大支持的触碰点数,做法如下:TouchPanelCapabilities tcs = TouchPanel.GetCapabilities(); /查詢觸控螢幕的基本功能有关 TouchPanelCapabilities 结构常用的属性请参考表3 的说明:表3:TouchPanelCapabilities 结构常用的属性属性名称说明IsConnected查询触控屏幕的可用状态。MaximumTouchCount取得支持使用者同时触碰触控屏幕的触碰点数量。 如果需要取得用户同时触碰屏幕的所有坐标点,则可以呼叫 TouchPanel 类别的 GetState 方法,取得所有触碰点的集合,再利用循环取出集合中的所有触碰点并加以处理,做法如下:TouchCollection tc = TouchPanel.GetState(); /取得觸控螢幕的狀態foreach (TouchLocation tl in tc) /取得所有的觸碰點 /利用 tl.Position 取得觸碰點座標说明请注意 GestureSample 结构的属性的型态为 TimeSpan 结构而不是 GameTime 类别,用来代表手势操作与手势操作之间的时间间隔。各种手势操作需要用到的 GestureSample 结构的属性可以参考表4 的详细说明:表4:各种手势操作需要用到的 GestureSample 结构的属性触控操作说明TapPosition 属性DoubleTapPosition 属性HoldPosition 属性VerticalDragPosition 属性和 Delta 属性HorizontalDragPosition 属性和 Delta 属性FreeDragPosition 属性和 Delta 属性DragComplete无FlickDelta 属性PinchPosition、Position2、Delta、和 Delta 2 四个属性PinchComplete无 处理手势操作的要诀在处理使用者的触控操作方面,Flick 触控操作可以利用 GestureSample 结构的 Delta 属性的内容值当做用户轻拂的快慢速度,以控制卷动游戏内容的速度。VerticalDrag 和 HorizontalDrag 触控操作可以利用 GestureSample 结构的 Delta 属性的内容值判断垂直和水平移动的距离,而且 VerticalDrag 触控操作的 Delta 属性的 X 成员的内容值必为 0,而 HorizontalDrag 触控操作的 Delta 属性的 Y 成员的内容值必为 0,不需要另外透过程序代码进行设定。Pinch 触控操作是两个手指头并用的触控操作,常常用来执行旋转对象、放大缩小对象、或是旋转相机镜头的动作。游戏程序可以利用 GestureSample 结构的 Position 属性和 Delta 属性,取得第一个手指头的触碰点和偏差量,利用 Position2 属性和 Delta2 属性取得第二个手指头的触碰点和偏差量,再据以执行变更游戏程序显示的内容的动作。 设计支持手势操作的 XNA 游戏了解 XNA Framework 支持触控操作的基本功能之后,接下来我们就要设计一个能够允许用户利用触控屏幕操作的简单游戏。首先请启动 Microsoft Visual Studio 2010 Express,建立型态为 XNA Game Studio(4.0) 型态的项目,然后于 Content Pipeline 项目中加入让使用者进行触控操作的图形的圆形档案,以及当圆形碰撞到游戏程序的窗口时欲发出的声响的声音文件。例如本范例准备了两个圆形的图案,名称为 Ball.png 的图形档案是一个圆形,名称为 HoldBall.png 的图形档案是一个中心有一个红点的圆形,用来表示被点选的图形,而 Hitwall.wav 则是当圆形的图案碰撞到游戏程序的窗口时欲发出的声音的声音文件。将游戏程序需要使用的资源加入到 Content Pipeline 项目之后,请开启游戏项目中的 Game1.cs 档案,于类别中加入以下的变量和属性宣告:Texture2D Ball; /管理圓形圖案的變數Texture2D HoldBall; /管理中心有紅點的圓形圖案的變數Vector2 BallPosition=Vector2.Zero; /記錄圓形圖案位置的變數bool isHold = false; /記錄使用者是否執行Hold式的觸控操作的變數SoundEffect HitWall; /管理圖案碰撞遊戲程式視窗的音效的變數SoundEffectInstance HitWallEffect; /管理欲播放的音效的變數Vector2 Velocity = Vector2.Zero; /記錄Flick操作速度的變數public const float Friction = 0.9f; /記錄摩擦力的變數public const float BounceMagnitude = .5f; /記錄反彈速度的變數public const float MinScale = .5f; /記載最小縮小比例的變數public const float MaxScale = 2f; /記載最大放大比例的變數private float scale = 1f; /記載目前比例的變數public float Scale /記載目前比例的屬性 get return scale; set scale=MathHelper.Clamp(value, MinScale, MaxScale);/控制縮放的比例的最大/最小值 准备好游戏程序需要的变量之后,请修改 Game1 类别的建构函式,在建立 GraphicsDeviceManager 类别的对象之后设定 GraphicsDeviceManager 类别的对象的 PreferredBackBufferHeight 属性和 graphics.PreferredBackBufferWidth 属性,将游戏程序的窗口设定成宽 480 x 高 800 的大小。编辑妥的 Game1 类别建构函式如下:public Game1() graphics = new GraphicsDeviceManager(this);/建立GraphicsDeviceManager類別的物件 Content.RootDirectory = Content; /設定載入遊戲資源的根路徑 graphics.PreferredBackBufferHeight = 800; /設定遊戲程式視窗的高度 graphics.PreferredBackBufferWidth = 480; /設定遊戲程式視窗的寬度 / Frame rate is 30 fps by default for Windows Phone. TargetElapsedTime = TimeSpan.FromTicks(333333); /設定 Update 方法被呼叫的頻率设定妥游戏程序窗口的大小之后请编辑 Game1 类别的 Initialize 方法,负责启用手势操作的功能,编辑妥的 Initialize 方法如下:protected override void Initialize() / TODO: Add your initialization logic here TouchPanel.EnabledGestures = GestureType.Hold | GestureType.Tap | GestureType.DoubleTap | GestureType.FreeDrag | GestureType.HorizontalDrag | GestureType.Flick | GestureType.Pinch; /啟用手勢操作功能 base.Initialize();启用手势操作功能之后请于 Game1 类别的 LoadContent 方法加入加载游戏资源的程序代码,编辑好的 LoadContent 方法如下: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 Ball = Content.Load(Ball); /載入圓形圖案 HoldBall = Content.Load(HoldBall); /載入中心有紅點的圓形圖案 BallPosition = new Vector2(Window.ClientBounds.Width - Ball.Width) / 2, (Window.ClientBounds.Height-Ball.Height)/2);/設定圓形圖案要顯示在視窗的正中央 / TODO: use this.Content to load your game content here HitWall = Content.Load(HitWall);/載入圓形圖案撞擊視窗邊界要發出的音效檔案 HitWallEffect = HitWall.CreateInstance(); /利用 SoundEffect 類別的物 /件建立 SoundEffectInstance 類別的物件 HitWallEffect.Apply3D(new AudioListener(), new AudioEmitter(); /呼叫SoundEffectInstance類別的 Apply3D 方法套用 3D 音效您可以视需要修改上述的程序代码加载的资源名称,以加载游戏程序执行时需要的资源。加载妥游戏程序需要使用的资源之后,请修改名称为 Update 的方法,以反应使用者的手势操作动作。加入手势控制功能的 Update 方法如下:protected override void Update(GameTime gameTime) / Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed) this.Exit(); / TODO: Add your update logic here while (TouchPanel.IsGestureAvailable) /判斷使用者是否執行了手勢操作 GestureSample gesture = TouchPanel.ReadGesture(); /讀取使用者的手勢操作 switch (gesture.GestureType) /判斷使用者的手勢操作型態 case GestureType.Tap: /Tap 操作 case GestureType.DoubleTap: /DoubleTap 操作 BallPosition.X=gesture.Position.X-Ball.Width/2; /設定圖案顯示在使用 BallPosition.Y=gesture.Position.Y-Ball.Height/2; /者觸碰的座標點 break; case GestureType.Hold: /Hold 操作 Rectangle BallRect = new Rectangle(0, 0, (int)(Ball.Width * Scale), (int)(Ball.Height * Scale); /計算圖形的矩形大小 if (BallRect.Contains(int)(gesture.Position.X - BallPosition.X), (int)(gesture.Position.Y - BallPosition.Y)/判斷觸碰點是否在矩形中 isHold = true; /將 IsHold 變數的內容值設定為 true break; case GestureType.FreeDrag: /FreeDrag 操作 BallPosition += gesture.Delta; /循著使用者拖曳的軌跡移動圖形 break; case GestureType.Flick: /Flick 操作 Velocity = gesture.Delta; /設定移動圖形的速度 break; case GestureType.Pinch: /Pinch 操作 Vector2 a = gesture.Position; /取得第一個觸碰點 Vector2 aOld = gesture.Position - gesture.Delta;/取得第一個觸碰點的起始位置 Vector2 b = gesture.Position2; /取得第二個觸碰點 Vector2 bOld = gesture.Position2 - gesture.Delta2;/取得第二個觸碰點的起始位置float d = Vector2.Distance(a, b); /計算兩個觸碰點之間的距離 float dOld = Vector2.Distance(aOld, bOld);/計算兩個原始座標之間的距離 float scaleChange = (d - dOld) * .01f; /計算距離的變化量Scale += scaleChange; /將距離變化量的 1/10 當做縮放的比例 break; BallPosition += Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; /依據Flick操作的速度移動圖形 Velocity *= 1f - (Friction * (float)gameTime.ElapsedGameTime.TotalSeconds);/利用磨擦係數減緩圖形的移動速度 float HalfWidth = (Ball.Width * Scale) / 2f; /取得圖形寬度的 1/2 float HalfHeight = (Ball.Height * Scale) / 2f; /取得圖形高度的 1/2 if (BallPosition.X Window.ClientBounds.Right Ball.Width * Scale) /判斷圖形是否觸及視窗的右邊界 BallPosition.X = Window.ClientBounds.Right Ball.Width * Scale; /設定圖形右上角點的X座標等於視窗右邊界 Velocity.X *= -BounceMagnitude; /設定反彈的速度為目前速度的一半 HitWallEffect.Play(); /播放碰撞視窗邊界的音效 if (BallPosition.Y Window.ClientBounds.Bottom Ball.Height * Scale) /判斷圖形是否觸及視窗的下邊界 BallPosition.Y = Window.ClientBounds.Bottom Ball.Height * Scale; /設定圖形右下角點的Y座標等於視窗下邊界 Velocity.Y *= -BounceMagnitude; /設定反彈的速度為目前速度的一半 HitWallEffect.Play(); /播放碰撞視窗邊界的音效 base.Update(gameTime);最后我们还要修改名称为 Draw 的方法,将游戏程序显示的图形显示在反应用户手势操作的位置上,做法如下:protected override void Draw(GameTime gameTime) GraphicsDevice.Clear(Color.CornflowerBlue); / TODO: Add your drawing code here spriteBatch.Begin(); /開始繪製遊戲內容 if (isHold) /如果圖形被使用點中 spriteBatch.Draw(HoldBall, BallPosition, null, Color.White, 0, Vector2.Zero, Scale, SpriteEffects.None, 0); /在指定的位置顯示中心有紅點的圓形 else spriteBatch.Draw(Ball, BallPosition, null, Color.White, 0, Vector2.Zero, Scale, SpriteEffects.None, 0); /在指定的位置顯示圓形 spriteBatch.End(); /結束繪製遊戲內容 base.Draw(gameTime);做好之后请执行 建置 项目的动作。 将设计妥的游戏程序部署到 Windows Phone 7 智能型手机因为 Windows Phone 7 仿真器不支持用户触控操作,所以允许使用者利用手势进行游戏操作的游戏程序必须部署到真实的 Windows Phone 7 智能型手机才能测试和手势操作有关的功能是否正确,无法透过 Windows Phone 7 仿真器进行测试,因为在一般计算机上执行的 Windows Phone 7 仿真器无法接受用户透过手势动作进行操作。提示如果用户所使用的计算机配备的是触控屏幕,则在配备触控屏幕的计算机执行的 Windows Phon
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 荆门市中储粮2025秋招财务资产岗高频笔试题库含答案
- 衢州市中储粮2025秋招面试专业追问题库仓储保管岗
- 中国广电林芝市2025秋招技术岗专业追问清单及参考回答
- 新疆地区中石油2025秋招笔试综合知识专练题库及答案
- 炼铁员工安全培训课件
- 榆林市中储粮2025秋招面试半结构化模拟题30问及答案
- 燃气泄漏培训考试题及答案
- 固原市中石化2025秋招笔试提升练习题含答案
- 国家能源阿拉善盟2025秋招化学工程类面试追问及参考回答
- 果洛藏族自治州中储粮2025秋招综合管理岗高频笔试题库含答案
- 儿科常用急救技术
- IT运维服务合同(模板)7篇
- 猫咖设计案例解析与方案模板
- 《模拟电子技术(第三版)》全套教学课件
- 子宫破裂护理常规课件
- (2025年)国家能源集团笔试试题(+答案)
- DB34∕T 4010-2021 水利工程外观质量评定规程
- 精神专科护士工作汇报
- 客户设备大修方案(3篇)
- 【01-暑假复习】初高衔接点03 因式分解含答案-2025年新高一数学暑假衔接讲练 (通)
- 2025年国有企业管理岗竞聘笔考试试题库及答案
评论
0/150
提交评论