[翻译]XNA外文博客文章精选之five


PS:自己翻译的,转载请著明出处

                                                               简单的样例游戏
                               在这个样例中,我们通过源代码知道这是一个掉字母的简单的代码。
                               首先我们需要知道游戏当前是什么状态。所以我创建一个枚举,它可以保存当前的游戏状态。
1 public enum GameState
2 {
3     StateMainMenu,
4     StatePlaying,
5     StateGameOver,
6     StateHelp,
7 }
                               现在我们需要在某处去保存关于字母的信息,这些字母是在屏幕中下落的。
                               这个类将需要保存字母的位置在屏幕上(x,y坐标)以及它所表示的字母(A到Z)。
                               我们同样添加一个颜色变量,所以这个文本可以改变颜色去使它看起来更酷。
1 public class FallingCharacter
2 {
3     public float X, Y;
4     Color color;
5     public char character;
6 }
                               里面的结构成员变量应该被设置:
1 public FallingCharacter(float x, float y, Color c,char character)
2 {
3      this.X = x;
4      this.Y = y;
5      this.color = c;
6      this.character = character;
7 }
                              现在我们需要绘制字母在屏幕上。我们将使用XNAFont类去绘制字母到屏幕上。
1 public void Render(XNAFont f)
2 {
3     f.OutputText(character.ToString(), (int)X, (int)Y, color);
4 }
                              现在为了这个游戏去工作,我们需要创建某些变量去保存当前的游戏状态。
 1 GameState currentState = GameState.StateMainMenu; //游戏的当前状态
 2 XNAFont textWriter;         //文本绘制器
 3 string WorkingDirectory; //当前调试目的的目录
 4 KeyboardState kbState; //保存键盘的输入状态
 5 Keys[] pressedKeys;     //当前压下键盘上的键的数组
 6 Queue<FallingCharacter> Letters = new Queue<FallingCharacter>(); //下落字母的表单
 7 Random rand = new Random();//产生随机数
 8 float nextLetterTime = 0.6f//下一个字母多久后开始
 9 int NextSpeedup = 20//每回答正确20个速度增加20
10 int iSpeed = 2//字母的下落速度
11 int Score=0//当前玩家的分数
                             我们将研究如何使用这些变量。
                             我已经改变了类的结构,这个结构是通过样本的向导产生的。在这种情况下,这样我可以传入命令行参数,以防它们需要:
                             这同样是一个好地方去获得当前的目录。
1 public Game1(string[] args)
2 {
3     WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
4     InitializeComponent();
5 }
                            不要忘记去执行释放对象的操作。
1 void WindowsGame_Exiting(object sender, GameEventArgs e)
2 {
3         textWriter.Dispose();
4 }
                            当游戏开始,让我们设置屏幕为800*600象素
1 void WindowsGame_Starting(object sender, GameEventArgs e)
2 {
3     graphics.BackBufferWidth = 800;
4     graphics.BackBufferHeight = 600;
5     graphics.ApplyChanges();
6 }
                            创建一个文本渲染,这样我们可以显示字母在屏幕上,以及玩家的分数。
1 textWriter = XNAFont.LoadFont(this.graphics.GraphicsDevice,WorkingDirectory + "\\Textures\\Lucidia_Console_40.dds.xml", WorkingDirectory + "\\Textures\\Lucidia_Console_40.dds");
                            让我们继续,并且得到当前的键盘状态。
1 kbState = Keyboard.GetState();
                            下一步是更新功能。我们将需要检查当前的键盘的状态,响应键盘的压下和移动下落的字母。
1 protected override void Update()
2 {
3      // The time since Update was called last
4      float elapsed = (float)ElapsedTime.TotalSeconds;
5 }
                            让我们得到键盘的状态。这个Keyboard类是一个XNA类。这个类有一个公开的属性功能GetState(),它返回当前的键盘状态。我们可以在这里检查错误,然而这是留给breivity.
                            GetPressedKeys()返回一个Keys的数组(一个键盘键的枚举)
1 Keys[] newKeys = (Keys[])kbState.GetPressedKeys();
                            让我检查键,看看是否是刚压下的。这样可以通过用之前压下的键和刚接收到压下的键相比较得出。如果新键与旧键不一样,则新压下的键将触发一个事件。
 1 if (pressedKeys != null)
 2 {
 3     foreach (Keys k in newKeys)
 4     {
 5          bool bFound = false;
 6          foreach (Keys k2 in pressedKeys)
 7          {
 8               if (k == k2)
 9               {
10                    bFound = true;
11                    break;
12                }
13          }
14          if (!bFound)
15          {
16               OnKeyPressed(k); //handle this key press
17           }
18      }
19 }
                             现在,让我们保存这个被压下的键,这样我们可以拿它与下一时间压下的结果相比较,看看是否有新键被压下。
1 pressedKeys = newKeys;
                             经管游戏已经开始了,让我们更新下落字母的位置。
1 if (currentState == GameState.StatePlaying)
2 {
3      foreach (FallingCharacter fc in Letters)
4      {
                             更新字母的Y坐标。这个数一直增加直到Y被计算从窗口的顶部到窗口的底部。
1 fc.Y += (elapsed * (float)(iSpeed * 40));
                             如果这个字母已经到了屏幕的底部,这个游戏就结束了。
1 if (fc.Y + 50 > graphics.BackBufferHeight)
2 {
3        currentState = GameState.StateGameOver;
4        Letters.Clear();
5        break;
6 }
                             虽然游戏已经开始了,经过一小段时间,我们需要抛出一个新的字母来从屏幕上下落。
1 nextLetterTime -= elapsed;
2 if (nextLetterTime <= 0 && currentState != GameState.StateGameOver)
                             让我们设置下一个字母出现的时间。这是基于当前游戏的速度,通过一组数字去产生一些很好的效果。
1 nextLetterTime = 0.75f - (iSpeed * .03f);
                             让我们设置新的字母沿着屏幕的宽度在一个随机的地方,减去一个fudge数,这样字母就不能跑到屏幕的右侧去了。
                             字母同样应该一开始在屏幕上是可见的。
                             让我们继续并且使文本是亮绿色,给它一个随机的字母。
1 Letters.Enqueue(new FallingCharacter(rand.Next(graphics.BackBufferWidth - 30), -30,  Color.LightGreen, (char)((int)'A' + rand.Next(25))));
2         }
3    }
4 // Let the GameComponents update
5         UpdateComponents();
6 }
                            绘制这个游戏是相当的简单和迅速的。
1 protected override void Draw()
2 {
3     // Make sure we have a valid device
4     if (!graphics.EnsureDevice())
5             return;
6     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
7     graphics.GraphicsDevice.BeginScene();
8     switch (currentState)
9     {
                            在主菜单上让我们显示某些文本给用户,让他们知道如何开始游戏。
1 case GameState.StateMainMenu:
2 {
3       textWriter.OutputText("Press Enter to begin", graphics.BackBufferWidth / 4, graphics.BackBufferHeight / 2, Color.White);
4 }
5 break;
                            当游戏开始时,分数和字母必须被绘制。
1 case GameState.StatePlaying:
2 {
3       textWriter.OutputText("Score: " + Score.ToString(), 1010, Color.White);
4       foreach (FallingCharacter fc in Letters)
5       {
6           fc.Render(textWriter);
7       }
8 }
9 break;
                           如果游戏结束,让我们显示"Game Over"画面给用户。
1 case GameState.StateGameOver:
2 {
3          textWriter.OutputText("Score: " + Score.ToString(), 1010, Color.White);
4          textWriter.OutputText("Game Over", graphics.BackBufferWidth / 3, graphics.BackBufferHeight / 2,Color.LightBlue);
5          textWriter.OutputText("Press Return to Continue", graphics.BackBufferWidth / 6, graphics.BackBufferHeight / 2 + 50, Color.LightBlue);
6 }
7 break;
                           现在让XNA创造奇迹吧!
1 // Let the GameComponents draw
2 DrawComponents();
3 graphics.GraphicsDevice.EndScene();
4 graphics.GraphicsDevice.Present();
                           让我们看下键压下的事件
1 public void OnKeyPressed(Keys k)
                           如果用户在主要的菜单或者在游戏结束画面时,让我们提示他们去压下Enter键当他们想要开始玩。
1 if ((currentState == GameState.StateMainMenu ||currentState == GameState.StateGameOver)&& k == Keys.Enter)
2 {
3     //Reset the state of the game
4     currentState = GameState.StatePlaying;
5     nextLetterTime = 0.0f;
6     NextSpeedup = 20
7     iSpeed = 1;
8     Score = 0;
9 }
                           如果玩家当前正在玩这个游戏,让我检查去看看压下的键是否与屏幕上最低的字母相同。如果它是,然后我们可以删除这个字母并且增加玩家的分数:
 1 else if (currentState == GameState.StatePlaying)
 2 {
 3     string sName = Enum.GetName(typeof(Keys),k);
 4     if (Letters.Count > 0 &&String.Compare(Letters.Peek().character.ToString(), sName) == 0)
 5     {
 6         Score += 100;
 7         Letters.Dequeue();
 8         NextSpeedup--;
 9         if (NextSpeedup <= 0)
10         {
11             iSpeed++;
12             NextSpeedup = 20;
13         }
14     }
15 }
                           最后如果用户压下escape退出游戏,不管屏幕上有什么。
1 if (k == Keys.Escape)
2 {
3      this.Exit();
4 }

源代码:http://www.ziggyware.com/readarticle.php?article_id=49
(完)
原文地址:https://www.cnblogs.com/315358525/p/1561987.html