Document directory
Basic xNa OOP for beginners
ByPercent20
German Translation
The problem:
Often overlooked in development is the beginner to a technology. this is defiantly prevalent in the xNa community as more and more tutorials come out only to show the coolest new thing that we have figured out how to do, and we want to share with everyone else so they can do it too.
But, what about everyone else that wants to learn how to do game development in xNa. as of now the only thing they can really do is goof around with writing all their code in the game1.cs file in the update draw etc... Methods with no real Object Oriented Programming (OOP) to help make things more organized.
Many people write xNa Program Logic in update and draw, which is acceptable for some simple instance programs, but for complex programs, this method means a messy code style.
One of your possible solutions:
There are a lot of beginners that may know conceptually how to use Oop, but not able to use it when it comes to actually programming. this tutorial is geared towards those people that just need a nudge in the right direction for things to start making sense with OOP. since we dont want to get too complex lets just start out with a basic sprite class that all sprites will inherit from.
Knowing OOP and Applying OOP in practice cannot be simply classified.
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Game { public class Sprite { private Texture2D _texture; protected Vector2 _position; private Color _tint = Color.White; public Color Tint { get { return _tint; } set { _tint = value; } } public Vector2 Position { get { return _position; } set { _position = value; } } public Texture2D Texture { get { return _texture; } set { _texture = value; } } public virtual void Update(GameTime gt){} public virtual void Draw(SpriteBatch sb) { sb.Draw(this.Texture, this.Position, this.Tint); } } }
So basically these are the basics that you need for each sprite that you want to use in your game. Lets run through it real quick.
This is a Sprite base class.
First, you have your properties which for a beginner is just enough to draw the sprite to the screen. you don't really need much more usually. there is the texture2d which is what you will use to give the spriteTextureTo load on the screen. You have a vector2 that is going to bePositionYou want that Sprite to draw on the screen. Then you haveColorSo you can set the tint of the sprite we have set this default to white so it shows the pure color of the sprite.
Basic Attributes of Sprite: texture + Position + color
Second, you have two virtual methods that can be overridden to allow functionality. as you can see there is the update method and the draw method. you will pretty much need both to do something with your Sprite. to put it simple form, sort of, you will call the update method of the sprite class in the update method of the main game loop, and the draw method of the sprite class in the draw method of the main game loop. I will give examples of both later on so if you didn't catch that don't worry.
Two methods are required, one for update and the other for draw.
Now that we have your base sprite class lets look at how it can be used. the following is a class for a ship that extends the sprite class and has some functionality in it. I am not going to code out everything but it has just enough to give you an idea of what's going on.
Then we can derive the required classes from the sprite base class.
using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework; namespace Game { class Ship : Sprite { public override void Update(GameTime gt) { // Call the method that moves the sprite // on the screen by adjusting // the position property that was inherited // from the Sprite base class } // No real need yet to override the draw method // but it is there for you to do so if need be // for example if you wanted to call a differnt // overload of the spritebatches draw method. } }
I left some basic comments in the code above to further explain what and where you can do things in code. basically though you will spend your time in the ship class writing your code for the ship class and not having to rewrite code that the sprite itself is needing. this is very useful because you don't want to rewrite the same code in several places then have to go back and change them in several places.
Inherited functions.
Finally, for our basics of OOP in xNa we will look at what needs to be done to setup these classes we created and how to use them. it is fairly simple and all done in the game1.cs file. what we are going to do is create a ship and just a Sprite so that you can see how they work. so lets do that then I'll give a tip on how to streamline the initial setup of these sprites.
First we will look at creating and initializing objects. We will need 3 things, Sprite object, ship object and a spritebatch object. So here is the code for initializing those objects.
Create a Sprite, ship, spritebatch
public class Game1 : Microsoft.Xna.Framework.Game { SpriteBatch spriteBatch; Sprite sprite; Ship ship; // skip some code to the initialize method protected override void Initialize() { spriteBatch = new SpriteBatch(graphics.GraphicsDevice); sprite = new Sprite(); // we will set a position so the sprites don't overlap // each other when drawn sprite.Position = new Vector2(100, 100); ship = new Ship(); ship.Position = Vector2.Zero; base.Initialize(); }
What we have done is created an instance of spritebatch, Sprite, and ship next step is to load up our sprites into each of the objects. so here is the appropriate code for that. remember this is just going to be the method used to load the textures to the sprites. this shoshould give you an understanding of what to do.
protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { sprite.Texture = content.Load<Texture2D>(@"sprite"); ship.Texture = content.Load<Texture2D>(@"ship"); } }
Here we have given the sprite and the ship textures to display on the screen. so now we have setup a Sprite and a ship, given them positions to draw, and given them the graphics needed to draw on the screen. next lets do the code to actually draw them on the screen so if you are setting stuff up on the fly while reading this you can actually see something up on the screen. so here is the code you will need to draw your sprites to the xNa window.
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); sprite.Draw(spriteBatch); ship.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
In the draw method we are calling the ship and sprite object's draw method and sending it the spritebatch so it may use that to draw to the screen. at this point you shoshould be able to actually see something on the screen. woohoo, but next how will you get the sprites to actually do anything? We'll call the update Methods of both the ship and the sprite objects. Here is the code to do this.
protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); sprite.Update(gameTime); ship.Update(gameTime); base.Update(gameTime); }
So now you can go in and play with the update method in ship class and get your ship to move around and do other stuff too. (I suggest not messing with the update class in the sprite class itself)
One quick thing. back up at the top of the Code where we initialized the objects I recommend setting some M constructors to make that easier so you don't have to call the properties all the time right after initialization. just a quick tip.
Using constructors is better than assigning values to attributes one by one.
I want to share some closing thoughts on this. this is only one of your ways to do OOP with xNa and is good for beginners doing things such as pong or space invaders or even a basic Super Mario Brothers type game. however, if you want to get more complex I suggest taking the concepts learned here and planning out a better way to do OOP for more complicated games. this is only meant to get started using OOP not to be the end all For OOP in xNa.
Use OOP in xNa.