• XNA 3.0初步——使用GameComponents


    1.7 使用GameComponents

    问题

    你想将应用程序分离为GameComponent 类,实现组件的复用。

    解决方案

    程序的特定部分可以从程序中分离出来。在一个XNA程序中,大多数此种类型的部分都需要被更新和绘制,例如粒子系统和billboard(通常翻译为公告板或广告牌)系统(见教程3-11和3-12)。

    正确的做法是为这些特定部分创建一个单独的类。在XNA Game 类中,创建这个类的实例,对它进行初始化,更新和绘制。所以你想让你的新类拥有自己的Initialize, (Un) LoadContent,Update和Draw方法,这让你就可以很容易地在Game类中调用它们了。

    如果你想在这个新类中定义这些方法,最好的方法就是从GameComponent类继承。你可以将这个类添加到Game类的Components集合中,这样当Game类初始化完成后就会调用GameComponent类的Initialize方法(如果你已经定义了一个)。 而且,每次Game类的Update方法调用后,GameComponent的Update方法也会自动被调用。

    如果你的组件还有绘制某些东西,你可以从DrawableGameComponent类继承而不是从GameComponent类,这样在组件类中还会包含一个Draw method,它会在Game类的Draw方法后被调用。

    注意在Game类的Initialize方法最后调用了base. Initialize,就是这个代码行调用了所有GameComponent类的Initialize方法,在其他方法中你也能看到类似的base.Update(gameTime),base.Draw(gameTime)。

    工作原理

    例如教程3-11中的billboarding代码封装在了一个GameComponent中。而且因为这个代码还需要绘制一些东西,所以使用的是DrawableGameComponent类。

    创建一个新的 (Drawable)GameComponent

    通过右击项目并选择Add →New File可以添加一个新的类文件,接着选择Class,我把它命名为BillboardGC。在这个新文件中添加XNA using代码行,只需将Game类的using复制到这个新类即可。

    下一步保证这个新类从GameComponent类或DrawableGameComponent类继承,如下面的代码所示。代码显示了如何创建教程3-11的billboarding。其中有些代码如CreateBBVertices 并没有写出,因为这个教程我们关注的是Initialize,LoadContent,Update和Draw方法。

    class BillboardGC : DrawableGameComponent
    {
        private GraphicsDevice device; 
        private BasicEffect basicEffect; 
        private Texture2D myTexture; 
        private VertexPositionTexture[] billboardVertices; 
        private VertexDeclaration myVertexDeclaration; 
        private List<Vector4> billboardList = new List<Vector4>(); 
        public Vector3 camPosition; 
        public Vector3 camForward; 
        public Matrix viewMatrix; 
        public Matrix projectionMatrix; 
        
        public BillboardGC(Game game) : base(game)
        {
        }
        
        public override void Initialize()
        {
            device = Game.GraphicsDevice; 
            base.Initialize(); 
        }
        
        protected override void LoadContent()
        {
            basicEffect = new BasicEffect(device, null); 
            myTexture = Game.Content.Load<Texture2D>("billboardtexture"); 
            AddBillboards(); 
            myVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements); 
        }
        
        public override void Update(GameTime gameTime) 
        {
            CreateBBVertices(); 
            base.Update(gameTime); 
        }
        
        . . . 
        
        public override void Draw(GameTime gameTime) 
        {
            //draw billboards . . . 
        }
    } 

    注意在Initialize方法中,你的component可以获取Game类,这样component就能获取Game类的公共字段,例如Game. GraphicsDevice和Game.Content。

    使用GameComponent

    定义完GameComponent类后,你就可以将它添加到Game类的GameComponent集合中,一旦添加后,GameComponent的注意方法就会自动被调用。最简单的方法就是创建一个GameComponent的实例并立即添加到Components集合中,最好的位置是在Game类的构造函数中。

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this); 
        Content.RootDirectory = "Content"; 
        Components.Add(new BillboardGC(this));
    } 

    这样一开始就能调用Initialize和LoadContent方法,并且在Game类的Update和Draw方法完成后调用这个新类的Update和Draw方法。有些情况下,你需要更新一些组件的公有变量。例如在billboarding组件中你需要更新camPosition和camForward变量调整View和Projection矩阵使之能正确地绘制到屏幕。因此,你应在Game类中添加一个组件变量。

    BillboardGC billboardGC; 

    然后存储这个组件并将它添加到Components集合中:

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this); 
        Content.RootDirectory = "Content"; 
        billboardGC = new BillboardGC(this); 
        Components.Add(billboardGC); 
    } 

    在Game类的Update方法中,你可以更新组件中的四个变量,在Update方法最后调用所有组件的Update方法,让billboarding组件进行更新:

    protected override void Update(GameTime gameTime)
    {
         . . . 
         billboardGC.camForward = quatCam.Forward; 
         billboardGC.camPosition = quatCam.Position; 
         billboardGC.viewMatrix = quatCam.ViewMatrix; 
         billboardGC.projectionMatrix = quatCam.ProjectionMatrix; 
         base.Update(gameTime); 
    }

    Game类的Draw方法更简单,只是在调用所有组件的Draw方法前清除背景:

    protected override void Draw(GameTime gameTime)
    {
        device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer,Color.CornflowerBlue, 1, 0); 
        base.Draw(gameTime); 
    } 

    最后一行代码会调用billboarding 组件的Draw方法,将billboards绘制到屏幕。

    代码

    GameComponent和Game类的Initialize,LoadContent,Update和Draw方法的代码已经在前面写过了。

    1

  • 相关阅读:
    HBase入门,看这一篇就够了
    【从零开始学CenterNet】6. CenterNet之loss计算代码解析
    cobbler使用DTK自动化做RAID
    linux批量免密登陆
    《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(下)
    《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(中)
    Python基础-v1
    js实现二维数组转置
    冰蝎3.0 流量特征分析 附特征
    关于 PDF相关整改建议的pdf后门事件分析
  • 原文地址:https://www.cnblogs.com/AlexCheng/p/2120179.html
Copyright © 2020-2023  润新知