如何在WP7上用XNA写2D游戏(四)


                                          3 章 创建XNA 游戏菜单
3.1 WP7XNA游戏的触控操作


      上一章节,我们了解了制作XNA 2D游戏的常用组件已及使用ScreenManage管理场景。可以说对XNA 2D游戏有了入门,不过我们玩游戏不会一开始就进入到游戏场景里的,总是会有启动界面,loading界面,然后到了游戏菜单。然后让用户选择开始继续帮助等选项,如下图3-1,就是一个常见的游戏界面。

         

 

3-1

 

PC上的运行的XNA游戏不同,我们在WP7上是靠触摸屏操作的,这和用鼠标操作还是不同的。那么我们就需要先了解WP7XNA的触控操作。

                                                         

现在的触摸屏手机基本都支持多点触控,比如拉伸,缩放,玩过Iphone上《愤怒的小鸟》就明白游戏画面可以用两个手指拉伸和缩放。还有很有名的《水果忍者》也是多点触控的好游戏,你用三个手指在屏幕上划拉,屏幕上就显出三个爪子印。

当然啦"单点触摸"也是支持的,你用一个指头也能操作的,比如你用一个指头在《愤怒的小鸟》里拉动弹弓。我们就从简单的单点触控开始了解吧。

当我们把一个指头在屏幕上操作,可能会有这样三种动作:按,移动,移开。就拿《愤怒的小鸟》里拉动弹弓这个动作,首先我们是按下一个指头,然后向后移动,然后在屏幕上移开这个手指。

那么这三个操作在WP7XNA里如何获取呢?我们就需要了解XNA里的TouchPanelTouchCollection这两个类。

 

 
  

 
  

 
  

 

 

 

和触控操作类似的还有叫“手势”的,也算复杂的触控吧。

TouchPanel.EnabledGestures = GestureType.FreeDrag;//用来指定手势,必须要先设定,否则报错

if (TouchPanel.EnabledGestures != GestureType.None)

{

switch (TouchPanel.ReadGesture())

{

case GestureType.Tap: //单击

break;

case GestureType.DoubleTap://双击

break;

case GestureType.FreeDrag://自由拖动

break;

case GestureType.DragComplete://拖动完成

break;

case GestureType.Flick://轻弹

break;

case GestureType.Hold://按住不动

break;

case GestureType.HorizontalDrag://横向拖动

break;

case GestureType.None://无手势

break;

case GestureType.Pinch://

break;

case GestureType.PinchComplete://捏完

break;

case GestureType.VerticalDrag://纵向拖动

break;

}

}

 

3.2        编写MenuEntry

如图3-1每一个菜单界面里都有多个菜单项,为了表示单个菜单项,我们就需要写一个MenuEntry类。

    菜单项可以在屏幕上输出文字来表示,为了美化还可以绘制图片来完成。菜单项一般都是纵向排列的,每个菜单项的坐标都不同,所以有这样两个属性:

        /// <summary>

        /// 菜单项文本内容

        /// </summary>

        public string Text

        {

            get { return text; }

            set { text = value; }

        }

 

        /// <summary>

        /// 菜单项文本的位置

        /// </summary>

        public Vector2 Position

        {

            get { return position; }

            set { position = value; }

        }

 

  由于每个菜单项都会响应点击事件,所以我们需要声明一个事件:

        /// <summary>

        ///菜单项的选中事件

        /// </summary>

        public event EventHandler Selected;

 

        /// <summary>

        ///选中菜单项函数

        /// </summary>

        internal void OnSelectEntry()

        {

            if (Selected != null)

            {

                isPress = true;

           

            }

        }

 

如果菜单项是图片构成的,为了让菜单项有按下动感,我们用图3-2里的三个图片来做一个三帧动画。


 

                                                    图3-2

      所以我们要用到四个变量:public Texture2D menuTexture,showTexture,pressTexture,releaseTexture;

      在菜单项的update函数里要做这样的处理

   private TimeSpan duration = TimeSpan.FromSeconds(0.4);//菜单动画的执行时间为0.2

   public void Update(bool isSelected, GameTime gameTime)

        {

            if(isPress)

            {

                duration -=gameTime.ElapsedGameTime;

               if (duration <= TimeSpan.FromSeconds(0.2)&& duration > TimeSpan.FromSeconds(0.1))

                {

                    showTexture = pressTexture; //0.2-0.1秒之间显示三张图片中第二个图片

                }

                else  if (duration<= TimeSpan.FromSeconds(0.1) &&duration>TimeSpan.Zero)

                {

                    showTexture =eleaseTexture;//0.1-0秒间显示三张图片中第三个图片

                }

                else if (duration <= TimeSpan.Zero)

                {

                    Selected(this, new PlayerIndexEventArgs(playerIndex));//菜单项按下动画完成触发Selected事件

                    duration = TimeSpan.FromSeconds(0.4);           

                    isPress = false;

                }

            }

        }

3.3 编写MenuScreen

      由于菜单界面也是一个特殊的场景,所以MenuScreen继承于GameScreen

   如图3-3MenuScreen类结构如下:



 

                       3-3

     我们着重分析下HandleInput方法:

public override void HandleInput(InputHelper input)

        {

                TouchCollection touchState =TouchPanel.GetState();

                bool  touchDetected = false; //是否触碰菜单

                Vector2 touchPosition = new Vector2();

               foreach(TouchLocation location in touchState)

               {

                     switch(location.State)

                    {

                             case TouchLocationState.Pressed:

                                      touchDetected = true;

                                      touchPosition = location.Position;

                                      break;

                             case TouchLocationState.Moved:

                                      break;

                             case TouchLocationState.Released:

                                      break;

                  }

               }

      if(touchDetected)

{

foreach (MenuEntrymenuEntry in menuEntries)

                    {

                            Rectangle    touchRect = new Rectangle((int)touchPosition.X - 5, (int)touchPosition.Y- 5,10, 10);

                            Rectangle entryRect = new Rectangle((int)menuEntry.Position.X- 5, (int)menuEntry.Position.Y -                 5,menuEntry.GetWidth(this), menuEntry.GetHeight(this));                             

                    if(entryRect.Intersects(touchRect)) //如果触摸点在菜单项的矩形区域内

               menuEntry.OnSelectEntry();//触发菜单选中事件。

                }

      }

      ………………….

}

3.4编写MainMenuScreen类

      对于游戏主菜单界面而言,点击“Play 菜单项意味着要切入到游戏主场景里,点击“Exit Game”菜单意味着退出游戏,那么就需要在MenuScreen扩展游戏场景切换的方法。在前一章节里我们简单介绍了游戏场景的管理类ScreenManager,在这里就派上用途了。

      首先我们让MainMenuScreen继承于MenuScreen:

public class MainMenuScreen:MenuScreen

      {

}

然后我们添加了如下等方法:

/// <summary>

           /// 增加菜单项

           /// </summary>

          /// <param name="name">菜单文字</param>

          /// <param name="screen">点击对应要启动的Screen</param>

          /// <param name="isExitItem">是否是退出菜单</param>

          /// <param name="isShowLoading">是否显示loading界面</param>

         /// <param name="position">菜单的坐标</param>
   public void AddMainMenuItem(string name, GameScreen screen, bool isExitItem, bool isShowLoading,Vector2 position)

       {

           this.isShowLoading= isShowLoading;

           MenuEntry entry = new MenuEntry(name,screen,isExitItem, position);

           entry.Selected += new System.EventHandler(entry_Selected);

           MenuEntries.Add(entry);

       }

       /// <summary>

       /// 菜单点击事件

       /// </summary>

       /// <param name="sender"></param>

       /// <param name="e"></param>

     void entry_Selected(object sender, EventArgs e)

       {

           MenuEntry menu = sender as MenuEntry;

           if(menu.IsExitItem) //如果是退出菜单

           {

               ScreenManager.Game.Exit();

           }

           else

           {          
                ScreenManager.AddScreen(menu.Screen,null);

           }

       }

此外,我们还需要写上InputHelper,修改上一章节的GameScreen类,ScreenManager类,在这两个类里加上对输入的支持。

GameScreen类里我们加上HandleInput方法:

                 public virtual void HandleInput(InputHelper input)

                 {
 

                 }

    ScreenManager里我们需要修改Update方法,增加对screen的输入响应:

       if(!otherScreenHasFocus)

        {

              screen.HandleInput(input);

              otherScreenHasFocus = true;

        }

      具体代码修改请看具体的XNAGameSample3这个Demo

     然后在Game1.cs里的Initialize()方法里我们就加上如下代码即可:

        MainMenuScreen mainMenu = newMainMenuScreen("Castle Defense");

        GameMainScreen main = new GameMainScreen();

        Vector2 position = new Vector2{ X = 0f, Y = 0f };

        mainMenu.AddMainMenuItem("Play", main, false,true, position);

        mainMenu.AddMainMenuItem("Exit", null,true, false,position);

        screenManager.AddScreen(mainMenu, null);
 

 最后的代码运行效果如图3-4



 

 

demo 下载地址:/Files/wangergo/XNAGameSample3.rar

 

转载于:https://www.cnblogs.com/wangergo/archive/2011/11/19/2255192.html

微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值