XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 Account settings
  Posted by: Anonymous
  When: 07/05/2014 at 09:48:39

 forced subtitle
  Posted by: Applefly
  When: 07/05/2014 at 06:00:48

 convert DVD into PMS
  Posted by: Applefly
  When: 07/05/2014 at 05:55:25

 DVD to Digital Copy easily
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:52:29

 DVD on Xbox 360/Xbox One Console
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:51:47

 Extract .Srt Subtitles
  Posted by: Applefly
  When: 04/05/2014 at 03:54:38

 Encode Movie collection
  Posted by: Applefly
  When: 04/05/2014 at 03:52:41

 Convert DVD to WMV
  Posted by: Applefly
  When: 29/04/2014 at 05:53:50

 rip DVDs into digital files
  Posted by: Applefly
  When: 29/04/2014 at 05:51:20

 iTunes movies/music to Kindle Fire
  Posted by: ciciyu80
  When: 29/04/2014 at 05:10:20


Ads

Adding camera delay - Lerp

Our flight simulator is almost finished. One of the most annoying things that remain is that your xwing responds instantaneous to your keyboard input. In fact, itís not this thatís annoying, itís that the camera responds instantaneous. This results in rather quirky camera behaviour.

Using the built-in functionality of XNA, this is extremely easy to resolve. What we are going to do, is make the camera a bit slower. To obtain this, we will separately keep track of the camera rotation. Now when the player presses some arrows, the xwing rotation will change immediately. Instead of immediately adjusting the camera rotation to these changes, we will make the camera rotation crawl slowly towards the xwing rotation. In other words, it will take a few frames before the camera rotation has become the same as the xwing rotation.

Start by adding a Quaternion variable to the top of your code, which weíll use to store the rotation of the camera:

 Quaternion cameraRotation = Quaternion.Identity;

Next, adjust the code in our UpdateCamera method so it uses this rotation instead of the xwing rotation:

 Vector3 campos = new Vector3(0, 0.1f, 0.6f);
 campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(cameraRotation));
 campos += xwingPosition;
 
 Vector3 camup = new Vector3(0, 1, 0);
 camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));

Now we still need to make our camera rotation follow the rotation of the xwing. This is what we will do: each frame we will make the camera rotation get 10% closer to the xwing rotation. This sounds very difficult, but using XNA itís not: just put this line as first line in the UpdateCamera method:

 cameraRotation = Quaternion.Lerp(cameraRotation, xwingRotation, 0.1f);

The Lerp function is one of the coolest functions in XNA. You can specify 2 Quaternions to the Lerp method, and specify you want to know what is 10% between the two of them. This is whatís done in the line above.

Even better, in XNA the Vector2, Vector3, Vector4, Matrix, Quaternion and maybe even some more objects have the Lerp function. So as an example you can better visualize: say you have two Vector2s: V1 = (10,50) and V2 = (20,100). If you use the line Vector2.Lerp(V1,V2,0.2f), this will give you 20% between V1 and V2, which is in this case (12,60). Youíll definitely going to use this function a LOT when you create a game.

Well thatís all there is to it, I wish it were more complicated but the Lerp function takes care of the difficult part for us. When you run this code, you will see your camera follows your xwing much smoother.




DirectX Tutorial 14 - Camera delay

If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



Click here to go to the forum on this chapter!

Or click on one of the topics on this chapter to go there:
  • Positioning the xwing
          Hello everyone, I was wondering if its possible to...
  • Dividing the code into classes
          Hi. I notice that practically the entire project i...
  • Score Request
          Hello all Thank you for these tutorials, they a...
  • Co-op
          Hi I have the XNA 3.0 Game Programming Recipes...
  • 1/2 Rendered
          Hi, My city is halfly rendered, after I put the...



    You can try these exercises to practice what you've learned:
  • Change the 0.1f into 0.01f and 0.5f and see what the difference is.
    This concludes the second series of XNA tutorials. Youíve come a long way, from drawing a simple triangle, to a real flight simulator! Of course, this is not the endpoint, so after you take a break, thereís a 3rd series waiting for you. This 3rd series will introduce you to HLSL, which is where the fun really begins.

    Our final code:

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using Microsoft.Xna.Framework;
     using Microsoft.Xna.Framework.Audio;
     using Microsoft.Xna.Framework.Content;
     using Microsoft.Xna.Framework.GamerServices;
     using Microsoft.Xna.Framework.Graphics;
     using Microsoft.Xna.Framework.Input;
     using Microsoft.Xna.Framework.Media;
     
     namespace Series3D2
     {
         public class Game1 : Microsoft.Xna.Framework.Game
         {
             enum CollisionType { None, Building, Boundary, Target }
     
             struct Bullet
             {
                 public Vector3 position;
                 public Quaternion rotation;
             }
     
             GraphicsDeviceManager graphics;
             SpriteBatch spriteBatch;
             GraphicsDevice device;
             Effect effect;
             Texture2D sceneryTexture;
             Model xwingModel;
             VertexBuffer cityVertexBuffer;
             Texture2D[] skyboxTextures;
             Model skyboxModel;
     
             int[,] floorPlan;
             int[] buildingHeights = new int[] { 0, 2, 2, 6, 5, 4 };
             Vector3 lightDirection = new Vector3(3, -2, 5);
             Vector3 xwingPosition = new Vector3(8, 1, -3);
             Quaternion xwingRotation = Quaternion.Identity;
             float gameSpeed = 1.0f;
             BoundingBox[] buildingBoundingBoxes;
             BoundingBox completeCityBox;
             const int maxTargets = 50;
             Model targetModel;

            List<BoundingSphere> targetList = new List<BoundingSphere> ();        Texture2D bulletTexture;

            List<Bullet> bulletList = new List<Bullet> ();        double lastBulletTime = 0;
            Vector3 cameraPosition;
            Vector3 cameraUpDirection;

             Quaternion cameraRotation = Quaternion.Identity;
     
             Matrix viewMatrix;
             Matrix projectionMatrix;
     
             public Game1()
             {
                 graphics = new GraphicsDeviceManager(this);
                 Content.RootDirectory = "Content";
             }
     
             protected override void Initialize()
             {
                 graphics.PreferredBackBufferWidth = 500;
                 graphics.PreferredBackBufferHeight = 500;
                 graphics.IsFullScreen = false;
                 graphics.ApplyChanges();
                 Window.Title = "Riemer's XNA Tutorials -- 3D Series 2";
     
                 lightDirection.Normalize();            
     
                 base.Initialize();
             }
     
             protected override void LoadContent()
             {
                 spriteBatch = new SpriteBatch(GraphicsDevice);
                 
                 device = graphics.GraphicsDevice;

                effect = Content.Load<Effect> ("effects");
                sceneryTexture = Content.Load<Texture2D> ("texturemap");            xwingModel = LoadModel("xwing");
                targetModel = LoadModel("target");

                bulletTexture = Content.Load<Texture2D> ("bullet");            skyboxModel = LoadModel("skybox", out skyboxTextures);

                LoadFloorPlan();
                SetUpVertices();
                SetUpBoundingBoxes();
                AddTargets();
            }

            private void LoadFloorPlan()
            {
                floorPlan = new int[,]
                {
                    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,1,1,0,0,0,1,1,0,0,1,0,1},
                    {1,0,0,1,1,0,0,0,1,0,0,0,1,0,1},
                    {1,0,0,0,1,1,0,1,1,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,1,1,0,0,0,1,0,0,0,0,0,0,1},
                    {1,0,1,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
                    {1,0,0,0,0,1,0,0,0,1,0,0,0,0,1},
                    {1,0,1,0,0,0,0,0,0,1,0,0,0,0,1},
                    {1,0,1,1,0,0,0,0,1,1,0,0,0,1,1},
                    {1,0,0,0,0,0,0,0,1,1,0,0,0,1,1},
                    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                };

                Random random = new Random();
                int differentBuildings = buildingHeights.Length - 1;
                for (int x = 0; x < floorPlan.GetLength(0); x++)
                    for (int y = 0; y < floorPlan.GetLength(1); y++)
                        if (floorPlan[x, y] == 1)
                            floorPlan[x, y] = random.Next(differentBuildings) + 1;
            }

            private void SetUpBoundingBoxes()
            {
                int cityWidth = floorPlan.GetLength(0);
                int cityLength = floorPlan.GetLength(1);


                List<BoundingBox> bbList = new List<BoundingBox> ();            for (int x = 0; x < cityWidth; x++)
                {
                    for (int z = 0; z < cityLength; z++)
                    {
                        int buildingType = floorPlan[x, z];
                        if (buildingType != 0)
                        {
                            int buildingHeight = buildingHeights[buildingType];
                            Vector3[] buildingPoints = new Vector3[2];
                            buildingPoints[0] = new Vector3(x, 0, -z);
                            buildingPoints[1] = new Vector3(x + 1, buildingHeight, -z - 1);
                            BoundingBox buildingBox = BoundingBox.CreateFromPoints(buildingPoints);
                            bbList.Add(buildingBox);
                        }
                    }
                }
                buildingBoundingBoxes = bbList.ToArray();

                Vector3[] boundaryPoints = new Vector3[2];
                boundaryPoints[0] = new Vector3(0, 0, 0);
                boundaryPoints[1] = new Vector3(cityWidth, 20, -cityLength);
                completeCityBox = BoundingBox.CreateFromPoints(boundaryPoints);
            }

            private void AddTargets()
            {
                int cityWidth = floorPlan.GetLength(0);
                int cityLength = floorPlan.GetLength(1);

                Random random = new Random();

                while (targetList.Count < maxTargets)
                {
                    int x = random.Next(cityWidth);
                    int z = -random.Next(cityLength);
                    float y = (float)random.Next(2000) / 1000f + 1;
                    float radius = (float)random.Next(1000) / 1000f * 0.2f + 0.01f;

                    BoundingSphere newTarget = new BoundingSphere(new Vector3(x, y, z), radius);

                    if (CheckCollision(newTarget) == CollisionType.None)
                        targetList.Add(newTarget);
                }
            }

            private void SetUpVertices()
            {
                int differentBuildings = buildingHeights.Length - 1;
                float imagesInTexture = 1 + differentBuildings * 2;

                int cityWidth = floorPlan.GetLength(0);
                int cityLength = floorPlan.GetLength(1);


                List<VertexPositionNormalTexture> verticesList = new List<VertexPositionNormalTexture> ();
                for (int x = 0; x < cityWidth; x++)
                {
                    for (int z = 0; z < cityLength; z++)
                    {
                        int currentbuilding = floorPlan[x, z];

                        //floor or ceiling
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2(currentbuilding * 2 / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 1)));

                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 1)));

                        if (currentbuilding != 0)
                        {
                            //front wall
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));

                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));

                            //back wall
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));

                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));

                            //left wall
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));

                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));

                            //right wall
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));

                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                            verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                        }
                    }
                }

                cityVertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, verticesList.Count, BufferUsage.WriteOnly);

                cityVertexBuffer.SetData<VertexPositionNormalTexture> (verticesList.ToArray());        }

            private Model LoadModel(string assetName)
            {

                Model newModel = Content.Load<Model> (assetName);            foreach (ModelMesh mesh in newModel.Meshes)
                    foreach (ModelMeshPart meshPart in mesh.MeshParts)
                        meshPart.Effect = effect.Clone();
                return newModel;
            }

            private Model LoadModel(string assetName, out Texture2D[] textures)
            {

                Model newModel = Content.Load<Model> (assetName);
                textures = new Texture2D[newModel.Meshes.Count];
                int i = 0;
                foreach (ModelMesh mesh in newModel.Meshes)
                    foreach (BasicEffect currentEffect in mesh.Effects)
                        textures[i++] = currentEffect.Texture;

                foreach (ModelMesh mesh in newModel.Meshes)
                    foreach (ModelMeshPart meshPart in mesh.MeshParts)
                        meshPart.Effect = effect.Clone();

                return newModel;
            }

            protected override void UnloadContent()
            {
            }

            protected override void Update(GameTime gameTime)
            {
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();

                ProcessKeyboard(gameTime);
                float moveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * gameSpeed;
                MoveForward(ref xwingPosition, xwingRotation, moveSpeed);

                BoundingSphere xwingSpere = new BoundingSphere(xwingPosition, 0.04f);
                if (CheckCollision(xwingSpere) != CollisionType.None)
                {
                    xwingPosition = new Vector3(8, 1, -3);
                    xwingRotation = Quaternion.Identity;
                    gameSpeed /= 1.1f;
                }

                UpdateCamera();
                UpdateBulletPositions(moveSpeed);

                base.Update(gameTime);
            }

            private void UpdateCamera()
            {

                 cameraRotation = Quaternion.Lerp(cameraRotation, xwingRotation, 0.1f);
     
                 Vector3 campos = new Vector3(0, 0.1f, 0.6f);
                 campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(cameraRotation));
                 campos += xwingPosition;
     
                 Vector3 camup = new Vector3(0, 1, 0);
                 camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));
     
                 viewMatrix = Matrix.CreateLookAt(campos, xwingPosition, camup);
                 projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);
     
                 cameraPosition = campos;
                 cameraUpDirection = camup;
             }
     
             private void ProcessKeyboard(GameTime gameTime)
             {
                 float leftRightRot = 0;
     
                 float turningSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
                 turningSpeed *= 1.6f * gameSpeed;
                 KeyboardState keys = Keyboard.GetState();
                 if (keys.IsKeyDown(Keys.Right))
                     leftRightRot += turningSpeed;
                 if (keys.IsKeyDown(Keys.Left))
                     leftRightRot -= turningSpeed;
     
                 float upDownRot = 0;
                 if (keys.IsKeyDown(Keys.Down))
                     upDownRot += turningSpeed;
                 if (keys.IsKeyDown(Keys.Up))
                     upDownRot -= turningSpeed;
     
                 Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), leftRightRot) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), upDownRot);
                 xwingRotation *= additionalRot;
     
                 if (keys.IsKeyDown(Keys.Space))
                 {
                     double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
                     if (currentTime - lastBulletTime > 100)
                     {
                         Bullet newBullet = new Bullet();
                         newBullet.position = xwingPosition;
                         newBullet.rotation = xwingRotation;
                         bulletList.Add(newBullet);
     
                         lastBulletTime = currentTime;
                     }
                 }
             }
     
             private void MoveForward(ref Vector3 position, Quaternion rotationQuat, float speed)
             {
                 Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
                 position += addVector * speed;
             }
     
             private CollisionType CheckCollision(BoundingSphere sphere)
             {
                 for (int i = 0; i < buildingBoundingBoxes.Length; i++)
                     if (buildingBoundingBoxes[i].Contains(sphere) != ContainmentType.Disjoint)
                         return CollisionType.Building;
     
                 if (completeCityBox.Contains(sphere) != ContainmentType.Contains)
                     return CollisionType.Boundary;
     
                 for (int i = 0; i < targetList.Count; i++)
                 {
                     if (targetList[i].Contains(sphere) != ContainmentType.Disjoint)
                     {
                         targetList.RemoveAt(i);
                         i--;
                         AddTargets();
     
                         return CollisionType.Target;
                     }
                 }
     
                 return CollisionType.None;
             }
     
             private void UpdateBulletPositions(float moveSpeed)
             {
                 for (int i = 0; i < bulletList.Count; i++)
                 {
                     Bullet currentBullet = bulletList[i];
                     MoveForward(ref currentBullet.position, currentBullet.rotation, moveSpeed * 2.0f);
                     bulletList[i] = currentBullet;
     
                     BoundingSphere bulletSphere = new BoundingSphere(currentBullet.position, 0.05f);
                     CollisionType colType = CheckCollision(bulletSphere);
                     if (colType != CollisionType.None)
                     {
                         bulletList.RemoveAt(i);
                         i--;
     
                         if (colType == CollisionType.Target)
                             gameSpeed *= 1.05f;
                     }
                 }
             }
     
             protected override void Draw(GameTime gameTime)
             {
                 device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);
     
                 DrawSkybox();
                 DrawCity();
                 DrawModel();
                 DrawTargets();
                 DrawBullets();
     
                 base.Draw(gameTime);
             }
     
             private void DrawCity()
             {
                 effect.CurrentTechnique = effect.Techniques["Textured"];
                 effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                 effect.Parameters["xView"].SetValue(viewMatrix);
                 effect.Parameters["xProjection"].SetValue(projectionMatrix);
                 effect.Parameters["xTexture"].SetValue(sceneryTexture);
                 effect.Parameters["xEnableLighting"].SetValue(true);
                 effect.Parameters["xLightDirection"].SetValue(lightDirection);
                 effect.Parameters["xAmbient"].SetValue(0.5f);
     
                 foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                 {
                     pass.Apply();
                     device.SetVertexBuffer(cityVertexBuffer);
                     device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.VertexCount/3);
                 }
             }
     
             private void DrawModel()
             {
                 Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(xwingRotation) * Matrix.CreateTranslation(xwingPosition);
     
                 Matrix[] xwingTransforms = new Matrix[xwingModel.Bones.Count];
                 xwingModel.CopyAbsoluteBoneTransformsTo(xwingTransforms);
                 foreach (ModelMesh mesh in xwingModel.Meshes)
                 {
                     foreach (Effect currentEffect in mesh.Effects)
                     {
                         currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
                         currentEffect.Parameters["xWorld"].SetValue(xwingTransforms[mesh.ParentBone.Index] * worldMatrix);
                         currentEffect.Parameters["xView"].SetValue(viewMatrix);
                         currentEffect.Parameters["xProjection"].SetValue(projectionMatrix);
                         currentEffect.Parameters["xEnableLighting"].SetValue(true);
                         currentEffect.Parameters["xLightDirection"].SetValue(lightDirection);
                         currentEffect.Parameters["xAmbient"].SetValue(0.5f);
                     }
                     mesh.Draw();
                 }
             }
     
             private void DrawTargets()
             {
                 for (int i = 0; i < targetList.Count; i++)
                 {
                     Matrix worldMatrix = Matrix.CreateScale(targetList[i].Radius) * Matrix.CreateTranslation(targetList[i].Center);
     
                     Matrix[] targetTransforms = new Matrix[targetModel.Bones.Count];
                     targetModel.CopyAbsoluteBoneTransformsTo(targetTransforms);
                     foreach (ModelMesh modmesh in targetModel.Meshes)
                     {
                         foreach (Effect currentEffect in modmesh.Effects)
                         {
                             currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
                             currentEffect.Parameters["xWorld"].SetValue(targetTransforms[modmesh.ParentBone.Index] * worldMatrix);
                             currentEffect.Parameters["xView"].SetValue(viewMatrix);
                             currentEffect.Parameters["xProjection"].SetValue(projectionMatrix);
                             currentEffect.Parameters["xEnableLighting"].SetValue(true);
                             currentEffect.Parameters["xLightDirection"].SetValue(lightDirection);
                             currentEffect.Parameters["xAmbient"].SetValue(0.5f);
                         }
                         modmesh.Draw();
                     }
                 }
             }
     
             private void DrawBullets()
             {
                 if (bulletList.Count > 0)
                 {
                     VertexPositionTexture[] bulletVertices = new VertexPositionTexture[bulletList.Count * 6];
                     int i = 0;
                     foreach (Bullet currentBullet in bulletList)
                     {
                         Vector3 center = currentBullet.position;
     
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 0));
     
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 1));
                         bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                     }
     
                     effect.CurrentTechnique = effect.Techniques["PointSprites"];
                     effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                     effect.Parameters["xProjection"].SetValue(projectionMatrix);
                     effect.Parameters["xView"].SetValue(viewMatrix);
                     effect.Parameters["xCamPos"].SetValue(cameraPosition);
                     effect.Parameters["xTexture"].SetValue(bulletTexture);
                     effect.Parameters["xCamUp"].SetValue(cameraUpDirection);
                     effect.Parameters["xPointSpriteSize"].SetValue(0.1f);
     
                     device.BlendState = BlendState.Additive;
     
                     foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                     {
                         pass.Apply();
                         device.DrawUserPrimitives(PrimitiveType.TriangleList, bulletVertices, 0, bulletList.Count * 2);
                     }
     
                     device.BlendState = BlendState.Opaque;
                 }
             }
     
             private void DrawSkybox()
             {
                 SamplerState ss = new SamplerState();
                 ss.AddressU = TextureAddressMode.Clamp;
                 ss.AddressV = TextureAddressMode.Clamp;
                 device.SamplerStates[0] = ss;
     
                 DepthStencilState dss = new DepthStencilState();
                 dss.DepthBufferEnable = false;
                 device.DepthStencilState = dss;
     
                 Matrix[] skyboxTransforms = new Matrix[skyboxModel.Bones.Count];
                 skyboxModel.CopyAbsoluteBoneTransformsTo(skyboxTransforms);
                 int i = 0;
                 foreach (ModelMesh mesh in skyboxModel.Meshes)
                 {
                     foreach (Effect currentEffect in mesh.Effects)
                     {
                         Matrix worldMatrix = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(xwingPosition);
                         currentEffect.CurrentTechnique = currentEffect.Techniques["Textured"];
                         currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
                         currentEffect.Parameters["xView"].SetValue(viewMatrix);
                         currentEffect.Parameters["xProjection"].SetValue(projectionMatrix);
                         currentEffect.Parameters["xTexture"].SetValue(skyboxTextures[i++]);
                     }
                     mesh.Draw();
                 }
     
                 dss = new DepthStencilState();
                 dss.DepthBufferEnable = true;
                 device.DepthStencilState = dss;
             }
         }
     }
     
     


    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2011 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2011 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    XNA 3.0 Recipes Book (8)
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Tutorials (160)
    XNA 4.0 using C# (89)
    2D Series: Shooters (22)
    3D Series 1: Terrain (13)
    3D Series 2: Flightsim (14)
    Starting point
    Textures
    Loading the floorplan
    Creating the 3D city
    Loading a Model
    Ambient and diffuse
    Quaternion camera
    Flight kinematics
    Collision detection
    Adding targets
    Point sprites
    Alpha blending
    Skybox
    Camera delay
    3D Series 3: HLSL (18)
    3D Series 4: Adv. terrain (19)
    Short Tuts (3)
    DirectX using C# (54)
    DirectX using C++ (15)
    DirectX using VB (2)
    -- Expand all --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!