Sunday, 1 March 2009

Tutorial 2: Sprites

Ok, so I said that next time we would me creating a level editor, I lied. I have decided to leave creating the level editor to the end. This way we won’t have to keep adding to it all the way through. Instead we are going to create a sprite class. This will be our base class for our enemies, towers etc. It’s going to hold the basic data about our sprites e.g. there texture, position and so on.

First off create a new class called “Sprite.cs” and add our basic using statements:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

From now on these need to be added to every new class we make. Ok, so let’s add some fields to the class.

protected Texture2D texture;
 
protected Vector2 position;
protected Vector2 velocity;
 
protected Vector2 center;
protected Vector2 origin;
 
protected float rotation;

All of these fields are quite self explanatory so I won’t bother explaining them. The reason all of these fields are protected is so all of the different classes that are going to be inherited from this class can access these fields whereas anything else will not have access to them.

Now what we need to do is add some properties like the sprites centre. The sprites centre needs to be accessible to things like towers so that they know if the sprite is in range etc.

public Vector2 Center
{
    get { return center; }
}

So, now that we have all of our fields and properties set up we can move onto our sprites constructor. For each new sprite we want to be able to pass in it’s position an it’s texture.

public Sprite(Texture2D tex, Vector2 pos)
{

Then we need to set up our fields based on the data being passed in.

texture = tex;
 
    position = pos;
    velocity = Vector2.Zero;
 
    center = new Vector2(position.X + texture.Width / 
        2, position.Y + texture.Height / 2);
    origin = new Vector2(texture.Width / 2, texture.Height / 2);
}

Again most of this is self explanatory. We are just initializing our fields values.

The sprite class has two methods, “Draw” and “Update” in the “Update” method all we do is update where the sprites centre is and all we do in the draw method is pass in a SpriteBatch and draw our texture.

public virtual void Update(GameTime gameTime)
{  
    this.center = new Vector2(position.X + texture.Width / 2,      
    position.Y + texture.Height / 2);
}
 
public virtual void Draw(SpriteBatch spriteBatch)
{  
    spriteBatch.Draw(texture, center, null, Color.White,      
        rotation, origin, 1.0f, SpriteEffects.None, 0);
}

Notice that these two methods are set as virtual. This is so and class that inherits from “Sprite.cs” can override these methods.

And that’s it for our sprite class. Next time we will be creating our enemy class.

13 comments:

  1. Thanks for doing these tutorials. I've been searching all over for xna tower defense tutorials, and this is truly helpful. Keep it going!

    ReplyDelete
  2. Please post more!

    ReplyDelete
  3. yea :) thank you very much been searching all over, please post more :)

    ReplyDelete
  4. FireFly, i read on the XNA forums that you were offering your code for inspection, if that's still the case, any chance you could send me an email (aer2@cox.net) with what you have for me to study?

    TIA

    ReplyDelete
  5. I am getting the error "'Microsoft.Xna.Framework.Vector2' is a 'type' but is used like a 'variable'" and can't figure out what's wrong. This is my code where I'm getting the error.

    public virtual void Update(GameTime gameTime)
    {
    this.center = Vector2(position.X + texture.Width / 2,
    position.Y + texture.Height / 2);
    }

    ReplyDelete
  6. Try :

    public virtual void Update(GameTime gameTime)
    {
    this.center = new Vector2(position.X + texture.Width / 2,
    position.Y + texture.Height / 2);
    }

    You missing the new keyword. Let me know if this helps!

    ReplyDelete
  7. Hey, for some reason i can't figure out i get the error:
    Error Property or indexer 'TowerDefense.Sprites.center' cannot be assigned to -- it is read only

    ReplyDelete
  8. thật ra có lúc vẩn sai là sao vậy ?

    ReplyDelete
  9. Hi there, just wondered how come you instantiate a new Vector2 type every update? isn't this bad practice? I mean, i am no pro coder or anything I just wondered if it shouldn't be Center.X = Texture.Width/2; Center.Y = Texture.Height/2; instead?

    I may be wrong but i was just wondering! great tutorial btw! :D

    ReplyDelete
    Replies
    1. Im wondering about this aswell

      Delete
    2. Ermm I'm not sure if this would be considered a bad practice, as Vector2 is a value type creating one doesn't cause garbage, however method calls can be pretty slow on the Xbox. My advice would be not to worry about it, I'm pretty sure this won't cause you any performance issues! The reason I wrote it like that is probably because I just pasted it from the Constructor ;)

      Delete
    3. Ahh allright, not that great with programming yet, but i've learned the basics from my 1st semester Computer-Science so far. Learning some XNA have been a great deal of fun so far. - This tutorial goes great with the XNA book i bought. More questions may come! Be warned. lol

      Delete
  10. To make the code a bit neater (just my personal preference) when declaring the class level variables, if there are no values associated with the variables you can lump them all together.

    So
    protected Texture2D texture;
    protected Vector2 position;
    protected Vector2 velocity;
    protected Vector2 center;
    protected Vector2 origin;
    protected float rotation;

    can become:
    protected Texture2D texture;
    protected Vector2 position, velocity, center, origin;
    protected float rotation;

    Just a FYI for all the beginner programmers.

    ReplyDelete