XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   2D Series finished!
My Book: Out Now!
      
       Go to section on this site

Additional info


Latest Forum posts

 error x3000:syntax error
  Posted by: Anonymous
  When: 02/09/2010 at 06:55:17

 Reflection problem in corners ...
  Posted by: Anonymous
  When: 31/08/2010 at 20:53:30

 OcTree Question
  Posted by: radulph
  When: 31/08/2010 at 18:00:04

 model problems
  Posted by: Archenon
  When: 30/08/2010 at 05:54:27

 Changing computer breaks my game
  Posted by: Archenon
  When: 30/08/2010 at 05:49:50

 model problems
  Posted by: muffinman
  When: 28/08/2010 at 16:58:10

 Vertices problem
  Posted by: Anonymous
  When: 27/08/2010 at 15:35:36

 Changing computer breaks my game
  Posted by: radulph
  When: 27/08/2010 at 07:12:24

 effects file and XNA 4.0 (Beta)
  Posted by: radulph
  When: 26/08/2010 at 06:33:33

 Changing computer breaks my game
  Posted by: radulph
  When: 26/08/2010 at 06:27:59


Ads

Alpha blending – Bullet collision

As a difficult audience, the result of last chapter probably didn’t fully please you. My guess is the black borders around our fireballs didn’t seem too normal to you. And you’re completely right, the borders should be blended with whatever is behind them. Welcome to this chapter on alpha blending.

Up till now, if 2 objects shared the same pixel, the pixel takes the color of the object closest to the camera. In the simplest form of alpha blending, the colors of both objects are added together, and the pixel takes the ‘sum’ of their colors. This is called “Additive alpha blending”.

For example. Imagine having a completely blue background. Adding a red triangle in front of it would now, with the current settings, simply display a red triangle. With additive alpha blending turned on, the pixel of the triangle would contain blue+red, thus the whole triangle would be purple.

Black is a special case. In terms of XNA, black isn’t a color. It’s nothing. So black+blue gives simply blue. In general, black + a color results in this color. This is why I’ve drawn the borders of the fireball black, because the more black the image gets, the more of the background will be let through.

When do we need to turn on alpha blending? We need our bullets to be blended with the background, but all the rest of our scene mustn’t change. So we need to turn on alpha blending before drawing our bullets, and turn it off again afterwards.

Add the following code to our DrawSprites method, before the call to effect.Begin:

 device.RenderState.AlphaBlendEnable = true;
 device.RenderState.SourceBlend = Blend.One;
 device.RenderState.DestinationBlend = Blend.One;

In short, when 2 objects compete for one pixel and alpha blending is turned on, this is how the final color is calculated:

    FinalColor = Color1*SourceBlend + Color2*DestinationBlend

Which gives in our case:

    FinalColor = Color1*1 + Color2*1

    FinalColor = Color1 + Color2

Told you, it’s simply the sum. It’s VERY important to disable alpha blending after we’ve drawn our bullets (otherwise, the next frame our entire scene would be rendered with additive alpha blending!), so put this line at the end of the method:

 device.RenderState.AlphaBlendEnable = false;

Running this should give you a MUCH nicer effect on your bullets!

We have nice-looking bullets, but what good are bullets if they don’t destroy our targets? Luckily, we already have a method that can check if 2 objects collide. So go to your UpdateBulletPositions method, and add this code to the end of the for-loop that scrolls through our bulletList:

 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;
 }

This code starts by creating a BoundingSphere object for each of our bullets. Next, you pass this to the CheckCollision method, which checks for possible collisions between this sphere and the buildings and targets in our city.

If there is a collision, the bullet is removed from the bulletList, making sure XNA never draws this bullet anymore. More important, if the bullet collided with a target, we increase the speed of our game with a notch. The CheckCollision method automatically takes care of the removal of the target.




DirectX Tutorial 12 - Alpha blending

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:
  • Alpha blending not working
          Hi guys, I just started to make a first person sho...
  • want to draw String ...
          hello everyone. i want to draw string by device b...
  • Great exercise!!
          The exercise below your tutorial in this chapter j...
  • Alpha blending in a 2D game
          Hi, I tried to use the same effect for my 2D ga...
  • Alpha Blending to .X file
          I have an Xfile model names "shirt.x" I loaded ...
  • Flightsim Error...
          I tried to complie XNA Flightsim tutorial but I fa...


    That will be all! With a 3D scene, our plane and some targets we can aim at and destroy, this is starting to look as a game. Let’s do something about that background.

    You can try these exercises to practice what you've learned:
  • Remove the line that turns off alpha blending, and see what’s going wrong.
    Our code:

     using System;
     using System.Collections.Generic;
     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.Net;
     using Microsoft.Xna.Framework.Storage;
     
     namespace XNAseries2
     {
         public class Game1 : Microsoft.Xna.Framework.Game
         {
             struct Bullet
             {
                 public Vector3 position;
                 public Quaternion rotation;
             }
     
             private struct VertexPointSprite
             {
                 private Vector3 position;
                 private float pointSize;
     
                 public VertexPointSprite(Vector3 position, float pointSize)
                 {
                     this.position = position;
                     this.pointSize = pointSize;
                 }
     
                 public static readonly VertexElement[] VertexElements =
                  {
                      new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),
                      new VertexElement(0, sizeof(float)*3, VertexElementFormat.Single, VertexElementMethod.Default, VertexElementUsage.PointSize, 0),
                  };
                 public static int SizeInBytes = sizeof(float) * (3 + 1);
             }
     
             enum CollisionType { None, Building, Boundary, Target }
     
             const int maxTargets = 50;
             int[] buildingHeights = new int[] { 0, 2, 2, 6, 5, 4 };
     
             GraphicsDeviceManager graphics;
             GraphicsDevice device;
     
             Effect effect;
             Vector3 lightDirection = new Vector3(3, -2, 5);
             Matrix viewMatrix;
             Matrix projectionMatrix;
     
             Texture2D sceneryTexture;
             Texture2D bulletTexture;
             Model xwingModel;
             Model targetModel;
     
             Vector3 xwingPosition = new Vector3(8, 1, -3);
             Quaternion xwingRotation = Quaternion.Identity;
     
             int[,] floorPlan;
             float gameSpeed = 1.0f;
     
             VertexBuffer cityVertexBuffer;
             VertexDeclaration texturedVertexDeclaration;
             VertexDeclaration pointSpriteVertexDeclaration;
     
             BoundingBox[] buildingBoundingBoxes;
             BoundingBox completeCityBox;
     

            List<BoundingSphere> targetList = new List<BoundingSphere> ();
            List<Bullet> bulletList = new List<Bullet> ();        double lastBulletTime = 0;

            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 -- Series 2";

                LoadFloorPlan();
                lightDirection.Normalize();
                SetUpBoundingBoxes();
                AddTargets();

                base.Initialize();
            }

            protected override void LoadContent()
            {
                device = graphics.GraphicsDevice;


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

                SetUpVertices();
                SetUpCamera();

                pointSpriteVertexDeclaration = new VertexDeclaration(device, VertexPointSprite.VertexElements);
            }

            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(device);
                return newModel;
            }

            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 SetUpCamera()
            {
                viewMatrix = Matrix.CreateLookAt(new Vector3(20, 13, -5), new Vector3(8, 0, -7), new Vector3(0, 1, 0));
                projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);
            }

            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, verticesList.Count * VertexPositionNormalTexture.SizeInBytes, BufferUsage.WriteOnly);

                cityVertexBuffer.SetData<VertexPositionNormalTexture> (verticesList.ToArray());
                texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);
            }

            protected override void UnloadContent()
            {
            }

            protected override void Update(GameTime gameTime)
            {
                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()
            {
                Vector3 campos = new Vector3(0, 0.1f, 0.6f);
                campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(xwingRotation));
                campos += xwingPosition;

                Vector3 camup = new Vector3(0, 1, 0);
                camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(xwingRotation));

                viewMatrix = Matrix.CreateLookAt(campos, xwingPosition, camup);
                projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);
            }

            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);
     
                 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);
                 effect.Begin();
                 foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                 {
                     pass.Begin();
                     device.VertexDeclaration = texturedVertexDeclaration;
                     device.Vertices[0].SetSource(cityVertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes);
                     device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes / 3);
                     pass.End();
                 }
                 effect.End();
             }
     
             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 mesh in targetModel.Meshes)
                     {
                         foreach (Effect currentEffect in mesh.Effects)
                         {
                             currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
                             currentEffect.Parameters["xWorld"].SetValue(targetTransforms[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 DrawBullets()
             {
                 if (bulletList.Count > 0)
                 {
                     VertexPointSprite[] spriteArray = new VertexPointSprite[bulletList.Count];
                     for (int i = 0; i < bulletList.Count; i++)
                         spriteArray[i] = new VertexPointSprite(bulletList[i].position, 50);
     
                     effect.CurrentTechnique = effect.Techniques["PointSprites"];
                     Matrix worldMatrix = Matrix.Identity;
                     effect.Parameters["xWorld"].SetValue(worldMatrix);
                     effect.Parameters["xView"].SetValue(viewMatrix);
                     effect.Parameters["xProjection"].SetValue(projectionMatrix);
                     effect.Parameters["xTexture"].SetValue(bulletTexture);
     
                     device.RenderState.PointSpriteEnable = true;
                     device.RenderState.AlphaBlendEnable = true;
                     device.RenderState.SourceBlend = Blend.One;
                     device.RenderState.DestinationBlend = Blend.One;
     
                     effect.Begin();
                     foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                     {
                         pass.Begin();
                         device.VertexDeclaration = pointSpriteVertexDeclaration;
                         device.DrawUserPrimitives(PrimitiveType.PointList, spriteArray, 0, spriteArray.Length);
                         pass.End();
                     }
                     effect.End();
     
                     device.RenderState.PointSpriteEnable = false;
                     device.RenderState.AlphaBlendEnable = false;
                 }
             }
         }
     }
     


    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 - 2008 Riemer Grootjans
  • Translations

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

    Microsoft MVP Award



    2007 - 2009 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 3.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!