Time to Do Something With It!



Finally! We get to see what we have been putting all this code together for. Make sure you have the two images from the beginning of this tutorial as part of your content project, and lets add a few lines of code to the Declarations section of our Game1.cs file:

        Texture2D t2dTanks;
        Texture2D t2dPrincess;
        MobileSprite myTank;
        MobileSprite mouseTank;
        MobileSprite myPrincess;


We will be drawing two tanks to the screen, and one pricess character. That's all we need for declarations, but we need to enable the mouse for this particular demonstration, so in your Initialize method, add the line:

            this.IsMouseVisible = true;


Next we need to load our content and set up our sprites. I'm going to do this in several parts, explaining each part in between:

            t2dTanks = Content.Load<Texture2D>(@"Textures\MulticolorTanks");
            t2dPrincess = Content.Load<Texture2D>(@"Textures\PrincessCharacter");


Standard texture loading stuff here. This should be familiar by now.

            myTank = new MobileSprite(t2dTanks);
            myTank.Sprite.AddAnimation("green", 0, 0, 32, 32, 8, 0.1f);
            myTank.Sprite.AutoRotate = true;
            myTank.Position = new Vector2(100, 100);
            myTank.Target = myTank.Position;
            myTank.AddPathNode(new Vector2(200, 200));
            myTank.AddPathNode(new Vector2(400, 200));
            myTank.AddPathNode(new Vector2(400, 400));
            myTank.AddPathNode(new Vector2(200, 400));
            myTank.Speed = 3;
            myTank.LoopPath = true;


Here we set up our first tank. After running the constructor and passing it the texture we are using, we add an animation called "green", which starts at 0,0 on the sprite sheet, is 32x32 pixels in size, and contains 8 frames. We want the frames to play for 0.1f seconds each.

We turn on Auto Rotation, and set the initial location for the tank to 100,100. We also set the tank's target to it's current position so that it doesn't run off to 0,0 before following it's pathing information.

Next, we add four pathing nodes for the tank. These nodes form a square near the center of the screen. We set the tank's speed to 3 and tell it we want the path to loop forever.

Lets add another tank:

            mouseTank = new MobileSprite(t2dTanks);
            mouseTank.Sprite.AddAnimation("red", 0, 32, 32, 32, 8, 0.1f);
            mouseTank.Sprite.AddAnimation("purple", 0, 128, 32, 32, 8, 0.1f, "red");
            mouseTank.Sprite.AddAnimation("yellow", 0, 64, 32, 32, 8, 0.1f);
            mouseTank.Sprite.AutoRotate = true;
            mouseTank.Position = new Vector2(100, 100);
            mouseTank.Target = mouseTank.Position;
            mouseTank.IsPathing = false;
            mouseTank.EndPathAnimation = "yellow";
            mouseTank.LoopPath = false;
            mouseTank.Speed = 2;


As you can see, we define this tank in a very different way. We have three animations, "red", "purple", and "yellow". The NextAnimation property of our "purple" animation is set to "red", meaning that when the purple animation plays it will play once, and go back to "red".

We also set an EndPathAnimation (to "yellow"). Note that since IsPathing is false, we won't use it right now, but we will change that a little later.

Again, the tank is going to AutoRotate, and we set an initial position, but we aren't going to use pathing information for this tank. Instead, this tank will "chase" the mouse cursor around.

Finally, lets add our Princess character:

            myPrincess = new MobileSprite(t2dPrincess);
            myPrincess.Sprite.AddAnimation("leftstop", 0, 0, 32, 64, 1, 0.1f);
            myPrincess.Sprite.AddAnimation("left", 0, 0, 32, 64, 4, 0.1f);
            myPrincess.Sprite.AddAnimation("rightstop", 0, 64, 32, 64, 1, 0.1f);
            myPrincess.Sprite.AddAnimation("right", 0, 64, 32, 64, 4, 0.1f);
            myPrincess.Sprite.CurrentAnimation = "rightstop";
            myPrincess.Position = new Vector2(100,300);
            myPrincess.Sprite.AutoRotate = false;
            myPrincess.IsPathing=false;
            myPrincess.IsMoving=false;


Our Princess has four animations defined. One each for walking left and right, and one each for facing left and right while stopped. As you can see, the "leftstop" and "rightstop" animations overlap the "left" and "right" animations, which is perfectly fine.

We set the CurrentAnimation to "rightstop" and set the position of the sprite. Then we turn off all of our options (AutoRotate, IsPathing, and IsMoving) since we want to control the princess with the keyboard.

Lets do our Draw method real quick (since it is easy) and we'll save update for last. Edit your Draw method to look like this:

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin();
            myTank.Draw(spriteBatch);
            mouseTank.Draw(spriteBatch);
            myPrincess.Draw(spriteBatch);
            spriteBatch.End();
 
            base.Draw(gameTime);
        }


Nothing at all out of the ordinary... we just start a SpriteBatch, draw our three objects, and end the SpriteBatch.

Now for Update. Again, I'm going to break this down into a couple of pieces. First, lets get the Keyboard and Mouse states:

            MouseState ms = Mouse.GetState();
            KeyboardState ks = Keyboard.GetState();


We will need those a little later. Now it is time to update our "pathing" tank:

            myTank.Update(gameTime);


Yep, that's it. He knows everything he is supposed to be doing already, so just calling update will cause him to follow his circuit around the screen over and over and over again.

Now lets look at our "mouseTank" object:

            mouseTank.Target = new Vector2(ms.X, ms.Y);
 
            if (ms.LeftButton == ButtonState.Pressed)
            {
                if (mouseTank.Sprite.CurrentAnimation == "red")
                {
                    mouseTank.Sprite.CurrentAnimation = "purple";
                }
            }
 
            mouseTank.Update(gameTime);


If we weren't demonstrating a "fire and forget" animation with this tank (the purple -> red animation) we would only have two lines here as well. We set the tank's target to the current location of the mouse. When mouseTank.Update is called, it will move towards that mouse point.

We also check to see if the left mouse button is clicked. If it is, and we are playing the "red" animation, we fire off the "purple" animation, which will play 8 frames as a purple tank and then go back to red.

Finally, lets add our princess to the game. There is a bit more code here because we are checking for player input:

            bool leftkey = ks.IsKeyDown(Keys.Left);
            bool rightkey = ks.IsKeyDown(Keys.Right);
 
            if (leftkey)
            {
                if (myPrincess.Sprite.CurrentAnimation != "left")
                {
                    myPrincess.Sprite.CurrentAnimation = "left";
                }
                myPrincess.Sprite.MoveBy(-2, 0);
            }
 
            if (rightkey)
            {
                if (myPrincess.Sprite.CurrentAnimation != "right")
                {
                    myPrincess.Sprite.CurrentAnimation = "right";
                }
                myPrincess.Sprite.MoveBy(2, 0);
            }
 
            if (!leftkey && !rightkey)
            {
                if (myPrincess.Sprite.CurrentAnimation == "left")
                {
                    myPrincess.Sprite.CurrentAnimation = "leftstop";
                }
                if (myPrincess.Sprite.CurrentAnimation == "right")
                {
                    myPrincess.Sprite.CurrentAnimation = "rightstop";
                }
            }
 
            myPrincess.Update(gameTime);


Here, we get the status of the left and the right keys. If the left or right key is pressed and we aren't already playing the corresponding animation, we start playing it. We also move 2 pixels in that direction. If neither key is pressed, the princess stops, and switches to either the leftstop or rightstop animations depending on what she was playing before stopping.

Fire it up! You should have a green tank running in circles, a red tank chasing your mouse (that turns purple if you click) and a princess you can walk back and forth with the left and right arrow keys.

Want more? Comment out the mouseTank code and replace it with this:

            if (ms.LeftButton == ButtonState.Pressed)
            {
                mouseTank.AddPathNode(ms.X, ms.Y);
                if (mouseTank.Sprite.CurrentAnimation != "red")
                    mouseTank.Sprite.CurrentAnimation = "red";
            }
 
            mouseTank.Update(gameTime);


Also, go up to your LoadContent method where we define mouseTank and change IsPathing to true. Now when you run the program you will have a tank that starts out red and waits for you to click the mouse. When you do, it will move to whatever points you click on. When it has reached the last point it will turn yellow and wait for more clicks.

As you can see, this new set of classes gives us some nice ways of handling animated sprites. And remember, sprites don't have to just be players and enemies. Animated interface objects can be created as sprites and can handle all of their own animation after you start them off.




































 

 
 
Site Contents Copyright 2006 Full Revolution, Inc. All rights reserved.
This site is in no way affiliated with Microsoft or any other company.
All logos and trademarks are copyright their respective companies.
RSS FEED