zoukankan      html  css  js  c++  java
  • [翻译]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
    (完)
  • 相关阅读:
    【转】sql server编写通用脚本自动检查两个不同服务器的新旧数据库的表结构差异
    Pytest 2
    【转】python通过SMTP协议发送邮件失败,报错505或535
    【转】环境搭建之allure的安装配置,及简单使用
    Pytest 1
    替换姓名为隐式
    docker 用户组权限
    安装go环境
    Win10配置WSL2安装Ubuntu,并支持Nvidia CUDA 环境
    miniconda源配置
  • 原文地址:https://www.cnblogs.com/315358525/p/1561987.html
Copyright © 2011-2022 走看看