上节内容中,我们已经有了第一个三维物体,本节中我们就先让它拥有最基本的平移和缩放的运动。
回顾我们的BasicEffect,它有一个World属性是用于决定物体坐标系的,如果我们对这个属性施加一些运算,就可以让物体动起来。通常,World的取值是单位矩阵,即物体位于原点处。要让物体发生移动,只需要在对应的坐标轴上与一个矩阵相乘。这个矩阵的构造方法是:
Matrix CreateTranslation(float xPosition, float yPosition, float zPosition);
三个参数分别代表在x、y、z三个坐标轴上的偏移量。
同理,缩放变化也是将一个缩放矩阵与物体所在位置的矩阵相乘,构造缩放矩阵的方法是:
Matrix CreateScale(float xScale, float yScale, float zScale);
同样的,三个参数分别代表在x、y、z三个坐标轴上的缩放的比例。如果想在三个轴上做相同比例的等比缩放,可以使用:
Matrix CreateScale(float scale);
沿用上节课我们建好的XNA项目,在VS2010中打开该项目。打开Game1.cs文件,我们来修改Game1类。为其添加两个成员变量,分别代表平移矩阵和缩放矩阵:
Matrix translateMatrix=Matrix.Identity;
Matrix scaleMatrix=Matrix.Identity;
然后在Draw()方法中修改basicEffect对象的World属性:
basicEffect.World= scaleMatrix * translateMatrix;
为了增加效果,我们不妨增加一点交互,即每点击一次屏幕,就让物体发生一点运动,从而可以更好的观察物体运动的形态。这样的交互肯定是要放在Update()方法当中的,要做的就是每次点击屏幕时调整平移矩阵和缩放矩阵的值(手势识别的方法在此不做介绍)。
最后,我们还可以将尝试修改平移矩阵和缩放矩阵的值以及二者相乘的顺序,观察最终的运动效果。
附本节Game1类的完整源码:
public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; Camera camera; Matrix world = Matrix.Identity; BasicEffect basicEffect; VertexPositionColor[] triangle; Matrix translateMatrix=Matrix.Identity; Matrix scaleMatrix=Matrix.Identity; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Frame rate is 30 fps by default for Windows Phone. TargetElapsedTime = TimeSpan.FromTicks(333333); // Extend battery life under lock. InactiveSleepTime = TimeSpan.FromSeconds(1); graphics.IsFullScreen = true; } /// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } /// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { camera = new Camera(this, new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up, MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 50.0f); Components.Add(camera); basicEffect = new BasicEffect(GraphicsDevice); triangle = new VertexPositionColor[]{ new VertexPositionColor(new Vector3(0, 1, 0), Color.Red), new VertexPositionColor(new Vector3(1, -1, 0), Color.Green), new VertexPositionColor(new Vector3(-1,-1, 0), Color.Blue) }; } /// <summary> /// UnloadContent will be called once per game and is the place to unload /// all content. /// </summary> protected override void UnloadContent() { // TODO: Unload any non ContentManager content here } /// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); TouchPanel.EnabledGestures = GestureType.Tap; if (TouchPanel.IsGestureAvailable) { GestureSample gestureSample = TouchPanel.ReadGesture(); if (gestureSample.GestureType == GestureType.Tap) { translateMatrix *= Matrix.CreateTranslation(0.3f, 0, 0); scaleMatrix *= Matrix.CreateScale(0.9f); } } base.Update(gameTime); } /// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); basicEffect.World = scaleMatrix * translateMatrix; basicEffect.View = camera.view; basicEffect.Projection = camera.projection; foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, triangle, 0, 1); } base.Draw(gameTime); } }
——欢迎转载,请注明出处 http://blog.csdn.net/caowenbin ——