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

Putting Collision Detection into practice

This chapter, weíll put all weíve learned in the past 2 chapters together, and end up with fully working per-pixel collision detection. We will create 2 methods, which detect collision between our rocket and the terrain and players and another one that detects whether the rocket is still inside the screen.

Given the past 2 chapters, itís fairly easy to detect for collisions between the rocket and the terrain:

 private Vector2 CheckTerrainCollision()
 {
     Matrix rocketMat = Matrix.CreateTranslation(-42, -240, 0) * Matrix.CreateRotationZ(rocketAngle) * Matrix.CreateScale(rocketScaling) * Matrix.CreateTranslation(rocketPosition.X, rocketPosition.Y, 0);
     Matrix terrainMat = Matrix.Identity;
     Vector2 terrainCollisionPoint = TexturesCollide(rocketColorArray, rocketMat, foregroundColorArray, terrainMat);
     return terrainCollisionPoint;
 }

We create the transformation matrices for our rocket and foreground textures, and pass them together with their color arrays to the TexturesCollide method. This method will return (-1,-1) if no collision was detected, otherwise the screen coordinate of the collision will be returned. The result of this method will be returned by the CheckTerrainCollision method.

Next in line is the CheckPlayersCollision method, which promises to be a little more complex as there are multiple players, and some of them might no longer be alive. Start with this code:

 private Vector2 CheckPlayersCollision()
 {
     Matrix rocketMat = Matrix.CreateTranslation(-42, -240, 0) * Matrix.CreateRotationZ(rocketAngle) * Matrix.CreateScale(rocketScaling) * Matrix.CreateTranslation(rocketPosition.X, rocketPosition.Y, 0);
     for (int i = 0; i < numberOfPlayers; i++)
     {
         PlayerData player = players[i];
         if (player.IsAlive)
         {
             if (i != currentPlayer)
             {
                 int xPos = (int)player.Position.X;
                 int yPos = (int)player.Position.Y;
 
                 Matrix carriageMat = Matrix.CreateTranslation(0, -carriageTexture.Height, 0) * Matrix.CreateScale(playerScaling) * Matrix.CreateTranslation(xPos, yPos, 0);
                 Vector2 carriageCollisionPoint = TexturesCollide(carriageColorArray, carriageMat, rocketColorArray, rocketMat);
             }
         }
     }
     return new Vector2(-1, -1);
 }

First, the matrix of the rocket is created, as this remains the same for all players. Next, for each player we check whether the player is alive, and if it is not the player that shot the rocket, as otherwise there would be a collision the very moment the rocket was shot. If all of this is true, we create the matrix for the carriage of the current player, as explained in the previous chapter.

The matrices of the rocket and carriage are passed to the TexturesCollide method, and the result is stored in a the carriageCollisionPoint Vector2. Remember that this contains (-1,-1) if no collision was detected, which is what we check for in the next piece of code, which you should put immediately after the carriageCollisionPoint variable is filled:

 if (carriageCollisionPoint.X > -1)
 {
     players[i].IsAlive = false;
     return carriageCollisionPoint;
 }

If a collision between the rocket and the current carriage is detected, the IsAlive property of the colliding player is set to false and the method returns the collision point, which immediately termintates the method.

If no collision was detected, we should check for collisions between the rocket and the cannon of the current player. This is done exactly the same, only this time we create the matrix for the cannon, instead of for the carriage: (put this code after the previous lines)

 Matrix cannonMat = Matrix.CreateTranslation(-11, -50, 0) * Matrix.CreateRotationZ(player.Angle) * Matrix.CreateScale(playerScaling) * Matrix.CreateTranslation(xPos + 20, yPos - 10, 0);
 Vector2 cannonCollisionPoint = TexturesCollide(cannonColorArray, cannonMat, rocketColorArray, rocketMat);
 if (cannonCollisionPoint.X > -1)
 {
     players[i].IsAlive = false;
     return cannonCollisionPoint;
 }

Again, if a collision between the rocket and the cannon is detected, the screen position of the collision is returned. If no collision was detected, the code continues and the next iteration of the for loop these checks will be done for the next player. In case no collision was found between the rocket and any player, the for loop ends and the CheckPlayersCollision returns (-1,-1).

Finally, we need a method to check whether the rocket is still inside the window. This shouldnít be that difficult:

 private bool CheckOutOfScreen()
 {
     bool rocketOutOfScreen = rocketPosition.Y > screenHeight;
     rocketOutOfScreen |= rocketPosition.X < 0;
     rocketOutOfScreen |= rocketPosition.X > screenWidth;
             
     return rocketOutOfScreen;
 }

This checks whether the rocket is below the lower boundary, OR to the left of our window, OR to the right of our window. The result is true if any of them is true, and is returned to the calling code.

At this moment, we have created 3 methods that allow us to detect any possible collision. All we need is a general method that processes their results:

 private void CheckCollisions(GameTime gameTime)
 {
     Vector2 terrainCollisionPoint = CheckTerrainCollision();
     Vector2 playerCollisionPoint = CheckPlayersCollision();
     bool rocketOutOfScreen = CheckOutOfScreen();
 
     if (playerCollisionPoint.X > -1)
     {
         rocketFlying = false;

        smokeList = new List<Vector2> ();
        NextPlayer();
    }

    if (terrainCollisionPoint.X > -1)
    {
        rocketFlying = false;                

        smokeList = new List<Vector2> ();
        NextPlayer();
    }

    if (rocketOutOfScreen)
    {
        rocketFlying = false;

        smokeList = new List<Vector2> ();
        NextPlayer();                
    }
}

This method calls the three methods, and stores their results in three variables. The three if-blocks check whether any of them returned a collision. If this is the case, the rocket will no longer be drawn, the smokelist is reset and the next player is activated. At this moment, the three if-block do exactly the same, but I keep them separated as in later chapters the different collisions will lead to different explosions.

2 things we need to do: define the NextPlayer method and call this method from our Update method:

 if (rocketFlying)
 {
     UpdateRocket();
     CheckCollisions(gameTime);
 }

The NextPlayer method has to increment the currentPlayer value, and check whether the new player is still alive:

 private void NextPlayer()
 {
      currentPlayer = currentPlayer + 1;
      currentPlayer = currentPlayer % numberOfPlayers;
      while (!players[currentPlayer].IsAlive)
          currentPlayer = ++currentPlayer % numberOfPlayers;
 }

First, the currentPlayer value is incremented. Sinc this must not be larger than numberOfPlayers, we take the modulus. As an example, if numberOfPlayers = 4, when 3 is incremented to 4 this will be reset to 0.
Next, you check whether the new player is alive. If it isnít, you increment it again. The line inside the while loop does actually exactly the same as the first two lines together: the ++ before currentPlayer makes sure the value is incremented BEFORE the line is evaluated.

When this method returns, currentPlayer will hold the next player that is still alive.

Now, when all if this is added to your project in the correct way, your code should be able to detect any collision between the rocket and any objects on its way!




DirectX Tutorial 16 - Putting CD into practice

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:
  • Collision Class?
          Hi, I am Trying to adapt this collision detection ...
  • No rockets, player switch..
          I thought I was following the tutorial fairly well...
  • Gametime
          I see that you added Gametime gameTime in the argu...
  • Player Reset?
          Hi, I am a very new to programming, and this tutor...
  • Transformation Matrix
          If I change the method of drawing the cannon as fo...
  • groundMatrix = Identity Matrix?
          Why is the terrainMatrix equal to the Identity mat...
  • Collision performance problems
          Hi everyone, I used the sample code in my own g...
  • Small Performance hint
          Hi Guys, if you have the same problem like me, ...
  • proformence when creating matric
          ive been trying to get pixel collision working for...
  • Problems with rocket flying
          so i was following the tutorials all the way up un...
  • Current Player Problem
          I am having some problems. When I first run my gam...
  • Error when I try to run.
          So, after a lot of problems, i had the code workin...
  • collision performance issues
          I used the collision algorithm from this tutorial ...
  • Need some help on runtime error
          Hi, First of all thank you for those great tutori...
  • Walking on terrain made like yours
          Hi, firstly- thanks Riemer for the great tuts! i...
  • Bug in player switching
          Hello Riemer, i noticed a bug in player swicthing,...


    A quick note on the performance of this method: a lot of calculations and checks need to be done for each pixel of image 1. This means, that when checking for collisions between 2 images, you should pass the smallest as tex1 and the largest as tex2. Furthermore, instead of blindly performing this detailed check between all of your images, you should first check whether the images possible overlap by checking whether their outlines collide. If their outlines donít collide, youíre sure there is no collision so itís useless to call the calculation-intensive TexturesCollide method on them.

    If youíre unsure about where some part of the code should be placed, have a look at the code below:

     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 XNATutorial
     {
         public struct PlayerData
         {
             public Vector2 Position;
             public bool IsAlive;
             public Color Color;
             public float Angle;
             public float Power;
         }
     
         public class Game1 : Microsoft.Xna.Framework.Game
         {
             GraphicsDeviceManager graphics;
             SpriteBatch spriteBatch;
             GraphicsDevice device;
             Texture2D backgroundTexture;
             Texture2D foregroundTexture;
             Texture2D carriageTexture;
             Texture2D cannonTexture;
             Texture2D rocketTexture;
             Texture2D smokeTexture;
             Texture2D groundTexture;
             SpriteFont font;
             int screenWidth;
             int screenHeight;
             PlayerData[] players;
             int numberOfPlayers = 4;
             float playerScaling;
             int currentPlayer = 0;
             bool rocketFlying = false;
             Vector2 rocketPosition;
             Vector2 rocketDirection;
             float rocketAngle;
             float rocketScaling = 0.1f;

            List<Vector2> smokeList = new List<Vector2> ();        Random randomizer = new Random();
            int[] terrainContour;
            Color[,] rocketColorArray;
            Color[,] foregroundColorArray;
            Color[,] carriageColorArray;
            Color[,] cannonColorArray;

            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 2D XNA Tutorial";

                base.Initialize();
            }

            private void SetUpPlayers()
            {
                Color[] playerColors = new Color[10];
                playerColors[0] = Color.Red;
                playerColors[1] = Color.Green;
                playerColors[2] = Color.Blue;
                playerColors[3] = Color.Purple;
                playerColors[4] = Color.Orange;
                playerColors[5] = Color.Indigo;
                playerColors[6] = Color.Yellow;
                playerColors[7] = Color.SaddleBrown;
                playerColors[8] = Color.Tomato;
                playerColors[9] = Color.Turquoise;

                players = new PlayerData[numberOfPlayers];
                for (int i = 0; i < numberOfPlayers; i++)
                {
                    players[i].IsAlive = true;
                    players[i].Color = playerColors[i];
                    players[i].Angle = MathHelper.ToRadians(90);
                    players[i].Power = 100;
                    players[i].Position = new Vector2();
                    players[i].Position.X = screenWidth / (numberOfPlayers + 1) * (i + 1);
                    players[i].Position.Y = terrainContour[(int)players[i].Position.X];
                }
            }

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


                backgroundTexture = Content.Load<Texture2D> ("background");
                carriageTexture = Content.Load<Texture2D> ("carriage");
                cannonTexture = Content.Load<Texture2D> ("cannon");
                rocketTexture = Content.Load<Texture2D> ("rocket");
                smokeTexture = Content.Load<Texture2D> ("smoke");
                groundTexture = Content.Load<Texture2D> ("ground");
                font = Content.Load<SpriteFont> ("myFont");
                screenWidth = device.PresentationParameters.BackBufferWidth;
                screenHeight = device.PresentationParameters.BackBufferHeight;
                playerScaling = 40.0f / (float)carriageTexture.Width;

                GenerateTerrainContour();
                SetUpPlayers();
                FlattenTerrainBelowPlayers();
                CreateForeground();

                rocketColorArray = TextureTo2DArray(rocketTexture);
                carriageColorArray = TextureTo2DArray(carriageTexture);
                cannonColorArray = TextureTo2DArray(cannonTexture);
            }

            private void FlattenTerrainBelowPlayers()
            {
                foreach (PlayerData player in players)
                    if (player.IsAlive)
                        for (int x = 0; x < 40; x++)
                            terrainContour[(int)player.Position.X + x] = terrainContour[(int)player.Position.X];
            }

            private void GenerateTerrainContour()
            {
                terrainContour = new int[screenWidth];

                double rand1 = randomizer.NextDouble() + 1;
                double rand2 = randomizer.NextDouble() + 2;
                double rand3 = randomizer.NextDouble() + 3;

                float offset = screenHeight / 2;
                float peakheight = 100;
                float flatness = 70;

                for (int x = 0; x < screenWidth; x++)
                {
                    double height = peakheight / rand1 * Math.Sin((float)x / flatness * rand1 + rand1);
                    height += peakheight / rand2 * Math.Sin((float)x / flatness * rand2 + rand2);
                    height += peakheight / rand3 * Math.Sin((float)x / flatness * rand3 + rand3);
                    height += offset;
                    terrainContour[x] = (int)height;
                }
            }

            private void CreateForeground()
            {
                Color[,] groundColors = TextureTo2DArray(groundTexture);
                Color[] foregroundColors = new Color[screenWidth * screenHeight];

                for (int x = 0; x < screenWidth; x++)
                {
                    for (int y = 0; y < screenHeight; y++)
                    {
                        if (y > terrainContour[x])
                            foregroundColors[x + y * screenWidth] = groundColors[x % groundTexture.Width, y % groundTexture.Height];
                        else
                            foregroundColors[x + y * screenWidth] = Color.Transparent;
                    }
                }

                foregroundTexture = new Texture2D(device, screenWidth, screenHeight, false, SurfaceFormat.Color);
                foregroundTexture.SetData(foregroundColors);

                foregroundColorArray = TextureTo2DArray(foregroundTexture);
            }

            private Color[,] TextureTo2DArray(Texture2D texture)
            {
                Color[] colors1D = new Color[texture.Width * texture.Height];
                texture.GetData(colors1D);

                Color[,] colors2D = new Color[texture.Width, texture.Height];
                for (int x = 0; x < texture.Width; x++)
                    for (int y = 0; y < texture.Height; y++)
                        colors2D[x, y] = colors1D[x + y * texture.Width];

                return colors2D;
            }

            protected override void UnloadContent()
            {
            }

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

                ProcessKeyboard();
                UpdateRocket();

                if (rocketFlying)
                {
                    UpdateRocket();
                    CheckCollisions(gameTime);
                }

                base.Update(gameTime);
            }

            private void UpdateRocket()
            {
                if (rocketFlying)
                {
                    Vector2 gravity = new Vector2(0, 1);
                    rocketDirection += gravity / 10.0f;
                    rocketPosition += rocketDirection;
                    rocketAngle = (float)Math.Atan2(rocketDirection.X, -rocketDirection.Y);

                    for (int i = 0; i < 5; i++)
                    {
                        Vector2 smokePos = rocketPosition;
                        smokePos.X += randomizer.Next(10) - 5;
                        smokePos.Y += randomizer.Next(10) - 5;
                        smokeList.Add(smokePos);
                    }
                }
            }

            private void ProcessKeyboard()
            {
                KeyboardState keybState = Keyboard.GetState();
                if (keybState.IsKeyDown(Keys.Left))
                    players[currentPlayer].Angle -= 0.01f;
                if (keybState.IsKeyDown(Keys.Right))
                    players[currentPlayer].Angle += 0.01f;

                if (players[currentPlayer].Angle > MathHelper.PiOver2)
                    players[currentPlayer].Angle = -MathHelper.PiOver2;
                if (players[currentPlayer].Angle < -MathHelper.PiOver2)
                    players[currentPlayer].Angle = MathHelper.PiOver2;

                if (keybState.IsKeyDown(Keys.Down))
                    players[currentPlayer].Power -= 1;
                if (keybState.IsKeyDown(Keys.Up))
                    players[currentPlayer].Power += 1;
                if (keybState.IsKeyDown(Keys.PageDown))
                    players[currentPlayer].Power -= 20;
                if (keybState.IsKeyDown(Keys.PageUp))
                    players[currentPlayer].Power += 20;

                if (players[currentPlayer].Power > 1000)
                    players[currentPlayer].Power = 1000;
                if (players[currentPlayer].Power < 0)
                    players[currentPlayer].Power = 0;

                if (keybState.IsKeyDown(Keys.Enter) || keybState.IsKeyDown(Keys.Space))
                {
                    rocketFlying = true;

                    rocketPosition = players[currentPlayer].Position;
                    rocketPosition.X += 20;
                    rocketPosition.Y -= 10;
                    rocketAngle = players[currentPlayer].Angle;
                    Vector2 up = new Vector2(0, -1);
                    Matrix rotMatrix = Matrix.CreateRotationZ(rocketAngle);
                    rocketDirection = Vector2.Transform(up, rotMatrix);
                    rocketDirection *= players[currentPlayer].Power / 50.0f;
                }
            }

     
             private Vector2 TexturesCollide(Color[,] tex1, Matrix mat1, Color[,] tex2, Matrix mat2)
             {
                 Matrix mat1to2 = mat1 * Matrix.Invert(mat2);
                 int width1 = tex1.GetLength(0);
                 int height1 = tex1.GetLength(1);
                 int width2 = tex2.GetLength(0);
                 int height2 = tex2.GetLength(1);
     
                 for (int x1 = 0; x1 < width1; x1++)
                 {
                     for (int y1 = 0; y1 < height1; y1++)
                     {
                         Vector2 pos1 = new Vector2(x1, y1);
                         Vector2 pos2 = Vector2.Transform(pos1, mat1to2);
     
                         int x2 = (int)pos2.X;
                         int y2 = (int)pos2.Y;
                         if ((x2 >= 0) && (x2 < width2))
                         {
                             if ((y2 >= 0) && (y2 < height2))
                             {
                                 if (tex1[x1, y1].A > 0)
                                 {
                                     if (tex2[x2, y2].A > 0)
                                     {
                                         Vector2 screenPos = Vector2.Transform(pos1, mat1);
                                         return screenPos;
                                     }
                                 }
                             }
                         }
                     }
                 }
     
                 return new Vector2(-1, -1);
             }
     
             private Vector2 CheckTerrainCollision()
             {
                 Matrix rocketMat = Matrix.CreateTranslation(-42, -240, 0) * Matrix.CreateRotationZ(rocketAngle) * Matrix.CreateScale(rocketScaling) * Matrix.CreateTranslation(rocketPosition.X, rocketPosition.Y, 0);
                 Matrix terrainMat = Matrix.Identity;
                 Vector2 terrainCollisionPoint = TexturesCollide(rocketColorArray, rocketMat, foregroundColorArray, terrainMat);
                 return terrainCollisionPoint;
             }
     
             private Vector2 CheckPlayersCollision()
             {
                 Matrix rocketMat = Matrix.CreateTranslation(-42, -240, 0) * Matrix.CreateRotationZ(rocketAngle) * Matrix.CreateScale(rocketScaling) * Matrix.CreateTranslation(rocketPosition.X, rocketPosition.Y, 0);
                 for (int i = 0; i < numberOfPlayers; i++)
                 {
                     PlayerData player = players[i];
                     if (player.IsAlive)
                     {
                         if (i != currentPlayer)
                         {
                             int xPos = (int)player.Position.X;
                             int yPos = (int)player.Position.Y;
     
                             Matrix carriageMat = Matrix.CreateTranslation(0, -carriageTexture.Height, 0) * Matrix.CreateScale(playerScaling) * Matrix.CreateTranslation(xPos, yPos, 0);
                             Vector2 carriageCollisionPoint = TexturesCollide(carriageColorArray, carriageMat, rocketColorArray, rocketMat);
     
                             if (carriageCollisionPoint.X > -1)
                             {
                                 players[i].IsAlive = false;
                                 return carriageCollisionPoint;
                             }
     
                             Matrix cannonMat = Matrix.CreateTranslation(-11, -50, 0) * Matrix.CreateRotationZ(player.Angle) * Matrix.CreateScale(playerScaling) * Matrix.CreateTranslation(xPos + 20, yPos - 10, 0);
                             Vector2 cannonCollisionPoint = TexturesCollide(cannonColorArray, cannonMat, rocketColorArray, rocketMat);
                             if (cannonCollisionPoint.X > -1)
                             {
                                 players[i].IsAlive = false;
                                 return cannonCollisionPoint;
                             }
                         }
                     }
                 }
                 return new Vector2(-1, -1);
             }
     
             private bool CheckOutOfScreen()
             {
                 bool rocketOutOfScreen = rocketPosition.Y > screenHeight;
                 rocketOutOfScreen |= rocketPosition.X < 0;
                 rocketOutOfScreen |= rocketPosition.X > screenWidth;
     
                 return rocketOutOfScreen;
             }
     
             private void CheckCollisions(GameTime gameTime)
             {
                 Vector2 terrainCollisionPoint = CheckTerrainCollision();
                 Vector2 playerCollisionPoint = CheckPlayersCollision();
                 bool rocketOutOfScreen = CheckOutOfScreen();
     
                 if (playerCollisionPoint.X > -1)
                 {
                     rocketFlying = false;

                    smokeList = new List<Vector2> ();
                    NextPlayer();
                }

                if (terrainCollisionPoint.X > -1)
                {
                    rocketFlying = false;

                    smokeList = new List<Vector2> ();
                    NextPlayer();
                }

                if (rocketOutOfScreen)
                {
                    rocketFlying = false;

                    smokeList = new List<Vector2> ();
                    NextPlayer();
                }
            }

            private void NextPlayer()
            {
                currentPlayer = currentPlayer + 1;
                currentPlayer = currentPlayer % numberOfPlayers;
                while (!players[currentPlayer].IsAlive)
                    currentPlayer = ++currentPlayer % numberOfPlayers;
            }

     
             protected override void Draw(GameTime gameTime)
             {
                 GraphicsDevice.Clear(Color.CornflowerBlue);
     
                 spriteBatch.Begin();
                 DrawScenery();
                 DrawPlayers();
                 DrawText();
                 DrawRocket();
                 DrawSmoke();
                 spriteBatch.End();
     
                 base.Draw(gameTime);
             }
     
             private void DrawScenery()
             {
                 Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);
                 spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
                 spriteBatch.Draw(foregroundTexture, screenRectangle, Color.White);
             }
     
             private void DrawPlayers()
             {
                 foreach (PlayerData player in players)
                 {
                     if (player.IsAlive)
                     {
                         int xPos = (int)player.Position.X;
                         int yPos = (int)player.Position.Y;
                         Vector2 cannonOrigin = new Vector2(11, 50);
     
                         spriteBatch.Draw(cannonTexture, new Vector2(xPos + 20, yPos - 10), null, player.Color, player.Angle, cannonOrigin, playerScaling, SpriteEffects.None, 1);
                         spriteBatch.Draw(carriageTexture, player.Position, null, player.Color, 0, new Vector2(0, carriageTexture.Height), playerScaling, SpriteEffects.None, 0);
                     }
                 }
             }
     
             private void DrawText()
             {
                 PlayerData player = players[currentPlayer];
                 int currentAngle = (int)MathHelper.ToDegrees(player.Angle);
                 spriteBatch.DrawString(font, "Cannon angle: " + currentAngle.ToString(), new Vector2(20, 20), player.Color);
                 spriteBatch.DrawString(font, "Cannon power: " + player.Power.ToString(), new Vector2(20, 45), player.Color);
             }
     
             private void DrawRocket()
             {
                 if (rocketFlying)
                     spriteBatch.Draw(rocketTexture, rocketPosition, null, players[currentPlayer].Color, rocketAngle, new Vector2(42, 240), 0.1f, SpriteEffects.None, 1);
             }
     
             private void DrawSmoke()
             {
                 foreach (Vector2 smokePos in smokeList)
                     spriteBatch.Draw(smokeTexture, smokePos, null, Color.White, 0, new Vector2(40, 35), 0.2f, SpriteEffects.None, 1);
             }
         }
     }
     
     


    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)
    Starting a project
    Drawing fullscreen images
    Positioning images
    SpriteBatch.Draw()
    Rotation
    Keyboard input
    Writing text
    Angle to Direction
    Direction to Angle
    Smoke trail
    Manual texture creation
    Random terrain
    Texture to Colors
    Coll Detection Overview
    Coll Detection Matrices
    Putting CD into practice
    Particles
    Additive alpha blending
    Particle engine
    Adding craters
    Sound in XNA
    Resolution independency
    3D Series 1: Terrain (13)
    3D Series 2: Flightsim (14)
    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!