XNA入门教程----(二) 移动控制

上一章,我们主要介绍了

何谓XNA

并且做了第一个XNA HelloWorld

本文,将紧接着上文. 继续我们的XNA之旅.

 

上篇的最后,我们通过

MouseState ms=Mouse.GetState();//获得鼠标相关信息 

 

获得了鼠标的Point位置,让自己的图像显示在鼠标的位置,因此做到了自定义光标的功能.

现在,我们对XNA的控制器作全面阐述

 

XNA的控制器

在XNA的控制器,主要定义在 Microsoft.Xna.Framework.Input下,

分为以下几种

 

  1.  Mouse 鼠标
  2. Keyboard 键盘
  3. GamePad 手柄

 

 在默认模板建立的HelloWorld中,我们会发现

 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                
this.Exit();

 

 这其实就是判断如果按下了游戏手柄的Back按钮时,自动退出。

  同样,我们可以通过以上Input的相关state来获得相关输入端的操作,如按钮,位置等等。


 一个简单的例子

 

现在,我们尝试在界面中绘制一个简单的 sprite(精灵),并实现鼠标和键盘的同时控制

 

代码
 protected override void Update(GameTime gameTime)
        {
            KeyboardState state 
= Keyboard.GetState();
            
if (state.IsKeyDown(Keys.Up))
            {
                
this.Position.Y -= 10;
            }
            
if (state.IsKeyDown(Keys.Down))
            {
                
this.Position.Y +=10;

            }
            
if (state.IsKeyDown(Keys.Left))
            {
                
this.Position.X -= 10;

            }
            
if (state.IsKeyDown(Keys.Right))
            {
                
this.Position.X += 10;

            }
            
base.Update(gameTime);
        }

 

 

通过以上代码,我们实现了对键盘的简单监听。 

这样,当我们按下键盘上下左右后,我们的sprite就随之移动了。

代码
  protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.Draw(img, new Rectangle((int)Position.X,(int) Position.Y, 5080), Color.White);
            spriteBatch.End();
            
base.Draw(gameTime);
        }

 

如何操作鼠标呢?

 根据上面相似的逻辑,我们当然能得到鼠标的当前位置,但是,如果这样做,我们的sprite会直接从原先点瞬间移动到目标点,而没有中间的过渡过程。

 在正常的游戏中,以上逻辑往往比较复杂,中间充满着障碍物,怪物等。因此不可简单的通过point操作。

为了未来的可扩展性,这里我们最终使用a-star算法来处理这个问题。

至于何谓a-star,请关注这里 

这里,我们使用了Franco, Gustavo 写的a-star类库,来算出最短路径。

当然,我们这里的构建的障碍的空的。未来在真实的地图中,我们需要构建出相关的障碍。

首先,我们构建一个空的无障碍的点集用作描绘障碍

代码
 private byte[,] m_matrix;
  m_matrix 
= new byte[1024,1024];
            
// FIXME: in matrix ,the obstacle is 0 else is 1
            for (int y = 0; y < m_matrix.GetUpperBound(1); y++)
            {
                
for (int x = 0; x < m_matrix.GetUpperBound(0); x++)
                {
                    m_matrix[x, y] 
= 1;
                }
            }

 

 这里,如果有障碍则为0否则为1

代码
//在update中加入鼠标位置的最短路径计算
  MouseState state1 = Mouse.GetState();
            
if (state1.LeftButton == ButtonState.Pressed)
            {
                IPathFinder pathFinder 
= new PathFinderFast(m_matrix);
                pathFinder.Formula 
= HeuristicFormula.Manhattan;
                pathFinder.SearchLimit 
= 2000;
                m_path 
= pathFinder.FindPath(new Vector2((int)this.Position.X, (int)this.Position.Y), new Vector2(state1.X , state1.Y ));
            }
            
if (this.m_path != null && this.m_path.Count() != 0)
            {
                
int index = this.m_path.Count() - 1;
                
this.Position = new Vector2(this.m_path[index].X, this.m_path[index].Y);
                
this.m_path.RemoveAt(index);
                
return;
            }

 

以上代码,我们先获得了当前鼠标的位置,并计算出当前点到目标点的最短路径。

之后将其存储,这样,如果没有动作我们每次循环便可自动继续进行相关的自动移动了。

 

通过以上代码,我们实现了用鼠标或键盘的简单控制。

 

但是 

或许大家发现了,这里的sprite是单帧的移动并非动画,如何让人物运动起来?请关注下回分解。

 源文件下载

 To Be Continue.... 

 

本系列列表 

 

  1. XNA入门教程----(一) 

  2. XNA入门教程----(二) 移动控制

  3. XNA入门教程----(三) 简单的动画

 


posted @ 2010-01-19 16:49  Edwin Tai  阅读(5436)  评论(8编辑  收藏  举报