您的位置:首页 > 其它

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

2012-01-04 22:34 369 查看
在前文中,我们已经实现了加载复杂的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 ——
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: