创建Game Components

来源:互联网 发布:淘宝小号空包网 编辑:程序博客网 时间:2024/05/16 06:20

此文档是基于 XNA Beta 2的

     Game components是 XNA Framework 基础的一部分;他是用来统一game的对象数据的一种方法,由于他起的作用,这个Framework 里的game类就可以自由的使用他们了。创建一个game component 的目的是为了创建一个可重用的代码"块"(block),可以用他来完成很多事情。一个game component可以是一个简单的可以绘制到屏幕上2D精灵,也可以是一个高级的3D地形;game component可以用来做相当多的事情。为了让事情变得简单,我们将从创建一个在屏幕上绘制位图(bitmap)的组件开始。为了让我们的组件可以在屏幕上渲染数据,我们不能从GameComponent继承,而必须要从DrawableGameComponent继承。这样做是为了让我们可以访问一些用来在游戏中控制图形数据的重要的方法。

想了解更多关于GameComponent 和 DrawableGameComponent的信息请看文章结尾处。 点击这里。

     打开Visual C# Express (Game Studio Express),创建一个新工程;我给这个工程命名为"Tutorial1"。在你点击确定以后,IDE创建所有你需要的东西,包括一个基本的Game类,他的名字是"Game1.cs"。让我们继续添加一个组件吧,你可以通过点击"添加(Add)->新建项"(New Item),选择Game Component(我将他命名为"Sprite"),然后点击添加。

     在这个基本的game component模板加载后,第一件我们要做的事情就是将他从GameComponent类继承改为从DrawableGameComponent类继承。请参照下面的代码段进行修改。

// 将这一行...
public partial class Sprite : Microsoft.Xna.Framework.GameComponent
// 改成这样...
public partial class Sprite : Microsoft.Xna.Framework.DrawableGameComponent

     这将允许我们在恰当的时候重载Draw函数。让我们来重点看看我们要在屏幕上绘制位图需要哪些成员。恩,需要一个 ContentManager,一个SpriteBatch, 一个Texture2D 还有 一个 Rectangle (用来表示精灵要绘制到屏幕上的区域)。让我们将他们添加好然后继续...你可能还需要添加两个XNA Framwork库的引用。请确定Members Region(成员区域)在Sprite类里,而不是using语句所在的区域。

using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
...
#region Members
protected SpriteBatch m_sBatch;
protected ContentManager m_conManager;
protected Texture2D m_texture;
protected Rectangle m_dest = new Rectangle(0, 0, 0, 0);
#endregion

     现在我们拥有了一些可以使用的成员了。然而在我们继续深入研究之前,让我们先讨论在开发一个game component时的一些practice的标准。设计一个game component的步骤可以分为3-4个阶段(非drawable的component只要3个阶段)。第一阶段是构造函数;在这里进行所有一般的初始化操作还有将组件添加到services collection的操作(将在后面的指南里讨论)都是很重要的。不应该在构造函数里获取其他service的引用。获取Game.Services collection里的对象的引用的操作应该在Initialization 方法内进行 (阶段2).然后阶段 3是加载(load)和卸载(unload)任何我们使用的图形素材(content)。在我们的例子中,这些图形素材包括SpriteBatch 和 ContentManager 对象还包括Texture2D对象.这些方法在DeviceReset/Create/Lost 事件发生时调用,并且他们对于让应用程序在窗口大小改变或者最小化后能继续运行起着非常重要的作用。最后一个阶段所包含的方法在"game loop"中被循环调用。他们是Update和Draw(只是DrawableGameComponent类中有),他们可以用来移动对象和/或绘制对象。下面是我们每个阶段的代码,注释描述了每一步我们要做些什么。由于我们不需要在阶段1和2进行任何特定的初始化,所以我们只需要关心加载素材和绘制他们。我们使用素材管道来将图片加载到Texture2D中。等一会,我们将加载真正的素材到工程中。

加载 / 卸载 图形素材

protected override void LoadGraphicsContent(bool loadAllContent){    base.LoadGraphicsContent(loadAllContent);    if (!loadAllContent)        return;        // 创建一个新的content manager    //      - 这个类将帮助我们加载图片到纹理中
    m_conManager = new ContentManager(game.Services);        // 创建一个新的spritebatch        //      - 这个类将帮助我们绘制纹理到屏幕上
    m_sBatch = new SpriteBatch(this.GraphicsDevice);    // 加载纹理资源,ball.png    m_texture = m_conManager.Load<Texture2D>("ball");    // 创建目标矩形(rectangle).    //      - 这将用来表示精灵绘制的位置和大小。
    m_dest = new Rectangle(128, 128, m_texture.Width, m_texture.Height);}protected override void UnloadGraphicsContent(bool unloadAllContent){    base.UnloadGraphicsContent(unloadAllContent);    if (!unloadAllContent)        return;    // 释放纹理
    m_texture.Dispose();    // 释放SpriteBatch.    m_sBatch.Dispose();    // 释放素材管理器(content manager).    m_conManager.Dispose();}

     现在是添加绘制代码的时候了,让我们来在屏幕上绘制一些实实在在的东西吧。一个SpriteBatch 对象就可以帮助你将多个纹理渲染到屏幕上,对于要将成百个精灵立即渲染到屏幕上的情况SpriteBatch将能帮上很大的忙。

绘制

public override void Draw(GameTime gameTime){    m_sBatch.Begin(SpriteBlendMode.AlphaBlend);    m_sBatch.Draw(m_texture, m_dest, Color.Maroon);    m_sBatch.End();    base.Draw(gameTime);}

     这个指南的组件方面已经完成了。我们需要将这个素材(content)添加到我们的工程中。 在Game Studio Express进行这个操作非常方便,因为当我们添加一个素材项目的时候,他将被立即作为素材来构造(build)。我们这个指南中我使用的是一个PNG文件, "ball.png",这是一个24x24象素大小并且包含透明的用来创建一个球的图片。你可以通过右击下面的图片选择图片另存为来保存这个文件,将他保存在你的工程的目录里。当你完成这一切以后在你的工程的解决方案浏览器( Solution Explorer )内右击你的工程,选择“添加->现有项”,在文件类型内选择 "All Files",然后添加这个文件, ball.png。请确保这个资源的属性窗口内的名字为 "ball",只有这样你才能正确的加载这个资源。

     当你完成这些以后,你已经可以使用你的Sprite组件了!只需要在你的game类内创建一个引用,然后实例化他,并且将他添加到 Components collection中。这样做可以确保这个component的方法 (Update, Initialize, and Draw)能够在适当的时候被调用。

Sprite sprite;...sprite = new Sprite(this);...this.Components.Add(sprite);

当你构造并且运行你的应用程序后,你应该可以得到一个与下面截图相同的画面。这里有这个指南的源代码,点击 这里.

关于GameComponent and DrawableGameComponent更多的信息
 

     在Beta2中,只有不多的几种方法用来创建game component,取决于你的需求你可以选择其中任意一种方法。让我们来看看两个主要的component类吧, GameComponent 和 DrawableGameComponent. 从他们的名字中我们就能知道GameComponent不需要渲染任何东西而DrawableGameComponents则正好相反.

  • GameComponent
    • Interfaces

       

      • IGameComponent
      • IUpdateable
      • IDisposable
  • DrawableGameComponent
    • Interfaces

       

      • IGameComponent
      • IUpdateable
      • IDisposable
      • IDrawable

     你可以看到,这两个component是如此相似,差别只在于DrawableGameComponent多了LoadGraphicsContent/UnloadGraphicsContent两个protected方法还有一个Draw方法.既然我们想绘制一个精灵到屏幕上,那我们就需要从DrawableGameComponent继承了.如果我们希望的话,我们也可以简单的在一个类上直接实现IDrawable,IUpdateable和IGameComponent这几个接口,然后配合Game类使用