zoukankan      html  css  js  c++  java
  • XNA框架基础——从头开始

    从头开始

    您已经准备好了一切,现在就让我们开始编码吧!本节您将在XNA Studio模板的帮助下创建一个简单的游戏项目,然后在Update和Draw方法中添加少量代码以实现一些小功能。在下一小节学习了SpriteBatch类之后,您将创建您的第一个游戏。

    您的第一个项目

    打开XNA Game Studio Express,在菜单栏中选择“文件→新建项目”,在弹出的新窗口中选择“Windows Game”模板,然后在项目名称处输入新项目的名称,比如“HelloWorld”或者就使用默认的名称“WindowsGame1”,在位置处输入新项目的保存位置,最后点击“确定”按钮。另外,在该窗口中还可以创建基于初学者工具包的游戏项目,比如“Spacewar Windows Starter Kit”。如下图1-10所示:

    201007210905
    图1-10

    在新创建的项目中包含两个类文件:Game1.cs和Program.cs。其中Program.cs文件包含了该应用程序的入口点Main方法,如下所示:

    using (Game1 game = new Game1())
    {
    ..game.Run();
    } // using

    Game1.cs文件包含了类Game1(继承自类Microsoft.Xna.Framework.Game),它包含了之前讲过的三个方法:Initialize、Update和Draw。Initialize方法此时不执行任何操作,只是调用基类的Initialize方法进行基本的初始化操作。Update方法主要包含下面的几行代码,用来检查Gamepad上的“Back”按钮是否被按下,如果按下则退出游戏,否则调用基类的Update方法:

    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
       this.Exit();

    Draw方法主要执行一个操作,将游戏窗口的背景色设置成一个特定的颜色,如下所示:

    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    按F5运行

    现在按下键盘上的F5键,或者选择菜单栏上的“调试→启动调试”命令运行游戏,此时将弹出如图1-11-(1)所示的窗口,它的了蓝色背景就是在Draw方法中设置的。

    201007210906
    图1-11

    您也可以把背景色改为绿色,比如Color.Green,然后再按F5运行程序,可以得到如图1-11-(2)所示的窗口,代码如下:

    graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer,
      Color.Green, 1, 0);

    参数ClearOptions的默认值是ClearOptions.Target | ClearOptions.DepthBuffer,意思是背景色和Depth缓存都被清除。

    修改代码

    现在,您可以想一想如何修改您的代码来实现一些操作。比如,按下键盘上的Escape键可以退出游戏。之前说过,XNA默认的会在Update方法中检查Xbox 360控制器上的Back按钮是否被按下来决定是否退出游戏,代码如下:

    // Allows the default game to exit on Xbox 360 and Windows
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
    ButtonState.Pressed)
      this.Exit();

    在“第三章-辅助类”中您将学习到Input类的使用,不过现在您可以使用一种快速的方法来操作键盘,下面的代码演示了当您按下Escape键时也能退出程序:

    // Get current gamepad and keyboard states
    GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
    KeyboardState keyboard = Keyboard.GetState();
    // Back or Escape exits our game on Xbox 360 and Windows
    if (gamePad.Buttons.Back == ButtonState.Pressed ||
      keyboard.IsKeyDown(Keys.Escape))
      this.Exit();

    第二章将详细讨论Sprites的知识,不过现在您可以稍微提前一点来学习在游戏中加载图像:给游戏加上一个背景图,然后操作键盘或者GamePad来移动该背景图,就像在一个竞速游戏或者Tile引擎中的一样,这些在很多2D的角色扮演游戏中经常会用到。对于更加复杂的Tile引擎,您还会需要石头、草、水、泥土等texture,甚至在草和水之间加一些过渡纹理(Transition Textures)。这将需要更多的texture和自定义代码,不过这也不是很难,如果您真的对Tile引擎感兴趣,您在网络上可以找到很多相关的信息。

    在您的第一个项目中添加的texture如图1-12所示:

    201007210907
    图1-12

    要把这个texture(CityGroundSmall.jpg)加入到您的项目中,只需要在解决方案资源管理器(Solution Explorer)中把它拖拽到您的项目中即可,然后右键点击该文件查看“属性”,如图1-13所示:

    201007210908
    图1-13

    通常您可能只会看到一些“生成操作(Build Action)”和“复制到输出目录”的选项(比如,您可能想把一个.dll或者.xml文件包含进来)。但如果XNA Studio检测到受支持的内容文件格式,您还会看到一些高级属性,此时会有另外三个重要设置:资源名称(Asset Name)、内容导入器(Content Importer)、内容处理器(Content Processor)。其中资源名称在将来选择加载资源时使用,而且内容文件的资源名称必须是唯一的,不能有重复。对于内容导入器,您可以像图1-13-(1)所示的情况中选择“Texture-XNA Framework”,或者为.x类型的文件选择“模型导入器(Model Importer)”,或者为.fx类型的文件选择“特效导入器(Effect Importer)”,如图1-13-(2)所示。

    内容处理器则包含更多的选项,比如,为这里的texture(CityGroundSmall.jpg)可以选择“Texture (Sprite, 32bpp) - XNA Framework”或者“Texture (Model, DXT, mipmapped) - XNA Framework”。DXT是一种压缩格式,在dds类型的文件中也经常使用,而且在游戏中这种格式用于texture效果非常好,因为它的压缩比高达1:6(如果包含透明像素则是1:4),这意味着在硬盘和显卡内存中的相同大小的空间上您可以存放多达 6倍数量的texture。对于2D sprite通常最好不要进行压缩,因为查看它们实际尺寸的时候使用32bpp(bits per pixel)可以保证最好的质量。关于内容管道的内容在本部分随后将会讲到。

    现在如果您按下F5或者F6(生成解决方案)上述添加的texture将被处理,并在项目的输出文件夹中产生一个新的文件“CityGroundSmall.xnb”,而且在项目的输出窗口中会显示下面的信息:

    Building CityGroundSmall.jpg -> bin\x86\Debug\CityGroundSmall.xnb

    现在您要做的最后一件事就是加载已经导入的纹理文件,在Initialize方法中进行操作并且在类中添加一个变量backgroundTexture,并使用之前您指定的资源名称(Asset Name)(资源名称默认的是您添加的内容文件的名称)。要渲染您的texture到输出屏幕上,您需要下一章要讨论的SpriteBatch类,它先设置Alpha Blending,然后把texture画到sprite中,最后把所有东西都画到屏幕上,代码如下:

    Texture2D backgroundTexture;
    SpriteBatch sprites;
    protected override void Initialize()
    {
      backgroundTexture = content.Load<Texture2D>("CityGroundSmall");
      sprites = new SpriteBatch(graphics.GraphicsDevice);
      base.Initialize();
    } // Initialize()

    要显示背景您必须在Draw方法中启动SpriteBatch,并把texture渲染到sprites中:

    protected override void Draw(GameTime gameTime)
    {
      graphics.GraphicsDevice.Clear(Color.Green);
      
      sprites.Begin();
      sprites.Draw(backgroundTexture, Vector2.Zero, Color.White);
      sprites.End();
      base.Draw(gameTime);
    } // Draw(gameTime)

    上述代码将在您的输出屏幕的(0,0)坐标处显示该背景,SpriteBatch.Draw方法中的Color参数也可以重新设置,不过这里暂时并不重要。按下F5您将看到图1-14所示的结果:

    201007210909
    图1-14

    为您的项目做的最后一件事就是添加使用键盘或者GamePad来滚动背景的功能,这样您就可以把可滚动的Tile渲染到整个背景。像下面这样修改Update方法您将可以捕获键盘或者GamePad输入:

    float scrollPosition = 0;
    protected override void Update(GameTime gameTime)
    {
      // Get current gamepad and keyboard states
      GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
      KeyboardState keyboard = Keyboard.GetState();
      // Back or Escape exits our game on Xbox 360 and Windows
      if (gamePad.Buttons.Back == ButtonState.Pressed ||
        keyboard.IsKeyDown(Keys.Escape))
        this.Exit();
      // Move 400 pixels each second
      float moveFactorPerSecond = 400 *
      (float)gameTime.ElapsedRealTime.TotalMilliseconds / 1000.0f;
      // Move up and down if we press the cursor or gamepad keys.
      if (gamePad.DPad.Up == ButtonState.Pressed ||
        keyboard.IsKeyDown(Keys.Up))
        scrollPosition += moveFactorPerSecond;
      if (gamePad.DPad.Down == ButtonState.Pressed ||
        keyboard.IsKeyDown(Keys.Down))
        scrollPosition -= moveFactorPerSecond;
      base.Update(gameTime);
    } // Update(gameTime)

    前面几行代码和之前的例子是相同的。接下来要计算每一帧要移动多少像素,如果一秒钟只画一帧,那么变量moveFactorPerSecond的值就是400;如果一秒钟画60帧,那么一帧需要1/60秒,此时该变量的值就是400/60(其中gameTime.ElapsedRealTime表示相邻两帧之间的时间间隔)。

    每当用户按下Up或者Down键的时候变量scrollPosition的值都会发生变化,此时在Draw方法中把scrollPosition的值加到坐标y上,就可以把背景来回上下移动了,代码如下:

    protected override void Draw(GameTime gameTime)
    {
      graphics.GraphicsDevice.Clear(Color.Green);
    
      sprites.Begin();
      int resolutionWidth = graphics.GraphicsDevice.Viewport.Width;
      int resolutionHeight = graphics.GraphicsDevice.Viewport.Height;
      for (int x = 0; x <= resolutionWidth / backgroundTexture.Width;
        x++)
      for (int y = -1; y <= resolutionHeight / backgroundTexture.Height;
        y++)
      {
        Vector2 position = new Vector2(
          x * backgroundTexture.Width,
          y * backgroundTexture.Height +
          ((int)scrollPosition) % backgroundTexture.Height);
        sprites.Draw(backgroundTexture, position, Color.White);
      } // for for
      sprites.End();
      base.Draw(gameTime);
    } // Draw(gameTime)

    现在运行您的游戏就可以上下来回移动,这对于您的第一个小应用是不是很酷?

  • 相关阅读:
    安装python官方的mysql库“mysql-connector-python”
    ubuntu(Mint-17)修改dns
    Updating Protobuf and GRPC in Golang
    git切换到远程分支
    ubuntu下取代ping的好工具tcpping
    为什么利率上升,债券价格下降?
    关于债券之我的疑惑
    GitHub超详细图文攻略
    git——从远程库克隆
    git——添加远程库
  • 原文地址:https://www.cnblogs.com/AlexCheng/p/2120284.html
Copyright © 2011-2022 走看看