在Windows Phone中进行3D开发之十组件

        在前文中,我们已经实现了加载复杂的3D模型并在空间中进行控制,通常在一个游戏程序中,这样的3D模型有很多,如果每一个都在场景中去绘制,那么Draw()方法就会很复杂了,而且也不利于代码的复用。更好的方式是把这艘飞船实现为GameComponent,而且是DrawableGameComponent。接下来我们就来构造飞船组件。


        首先为项目中添加一个新元素,使用XNA中的GameComponent,在生成的代码中做如下修改:

                public class Ship :Microsoft.Xna.Framework.DrawableGameComponent

即将GameComponent改为DrawableGameComponent,然后加入Draw()方法。

                public override void Draw(GameTimegameTime)

同样使用Model model;和Matrix[] modelTransforms;两个成员变量用于保存模型和骨骼数据。并在Initialize()方法中完成加载,代码见下: 

        public override void Initialize()
        {
            model = Game.Content.Load<Model>(@"Models/wedge_player1");
            modelTransforms = new Matrix[model.Bones.Count];
            base.Initialize();
        }

        但是经过这样的封装以后,使用者无法进行坐标变换的控制了,因此,还需要提供三个用于坐标变换的矩阵。加入成员变量: 

        public Matrix worldMatrix {set;get;}
        public Matrix viewMatrix { set; get; }
        public Matrix projectionMatrix { set; get; }

        最后完成Draw()方法,代码如下: 

        public override void Draw(GameTime gameTime)
        {
            //GraphicsDevice.Clear(Color.CornflowerBlue);

            model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = viewMatrix;
                    effect.Projection = projectionMatrix;
                }
                mesh.Draw();
            }
            base.Draw(gameTime);
        }

        这样,这个Ship类就封装完成了,当在场景中使用时,需要创建一个ship对象:

                ship = new Ship(this);

然后将其加到Components中去:

                Components.Add(ship);

并在LoadContent()方法中为其指定变换参数: 

            ship.projectionMatrix = camera.projection;
            ship.viewMatrix = camera.view * Matrix.CreateTranslation(new Vector3(4, 0, 10));
            ship.worldMatrix = Matrix.CreateScale(-0.02f) * Matrix.CreateRotationZ(MathHelper.ToRadians(180))*Matrix.CreateTranslation(new Vector3(20,0,0));

        当然也可以同样在Update()方法中更新ship.worldMatrix以对其进行旋转、平移、缩放的操作。如果需要有多艘飞船的编队,只要多创建几个ship对象,分别为其设定到不同的坐标即可。这样一来,通过继承自GameCompenent进行游戏组件的封装,可以在代码的可复用性上取得收益。


        好了,我们已经有了更丰富的物体了,多生成几艘飞船试试,看看编队是否够壮观吧。


        附Ship类的源代码: 

    public class Ship : Microsoft.Xna.Framework.DrawableGameComponent
    {
        public Matrix worldMatrix {set;get;}
        public Matrix viewMatrix { set; get; }
        public Matrix projectionMatrix { set; get; }
        Model model;
        Matrix[] modelTransforms;

        public Ship(Game game)
            : base(game)
        {
            worldMatrix = Matrix.Identity;
            viewMatrix = Matrix.Identity;
            projectionMatrix = Matrix.Identity;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            model = Game.Content.Load<Model>(@"Models/wedge_player1");
            modelTransforms = new Matrix[model.Bones.Count];
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //GraphicsDevice.Clear(Color.CornflowerBlue);

            model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = viewMatrix;
                    effect.Projection = projectionMatrix;
                }
                mesh.Draw();
            }
            base.Draw(gameTime);
        }
    }

——欢迎转载,请注明出处 http://blog.csdn.net/caowenbin ——

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文斌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值