XNA 101 .Net

Learn how to program in C# while writing games in XNA Game Studio 3.0!
Our upcoming Silverlight book for beginners (includes a great chapter on game development in Silverlight!) Hello! Silverlight 2 with Dave Campbell, available online now!



Pages

Recent posts

Navigation

Archive

Blogroll

    Tampa Divorce Lawyer

    North of Tampa in Lutz, Florida. A Tampa Divorce Lawyer focusing on family, divorce, and real estate law.

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    Lesson 3: Sprites without Lymon

    Sprites are the building blocks for 2D games in XNA. If you've played any 2D games, you have seen sprites. Mario is a sprite. The Pac Man ghosts are sprites. Pretty much anything that moves in a 2D game is a sprite. In XNA, it's taken a step further. Pretty much anything that is displayed on the screen in a 2D XNA game, including a background image, is a sprite.

    Let me start off by apologizing for how technical this lesson turned out. I'm glossing over some things and skipping others, unfortunately in order to put together this simple sample there are some not-so-simple concepts that need to be introduced. The good news is that most of the real complicated stuff is stuff you can just copy verbatim for now and we'll cover the concepts in more depth going forward. Really focus on the code that goes in the Draw method, since that's what we'll be building on next time.  

    Here is a link to the MyFirstGame project for the following lesson including all code changes made during the lesson.

    http://www.bluerosegames.com/xna101/lessons/XnaLesson3.zip

    The Sprite Class

    Ok so since we have these things called sprites, there should be a class definition in XNA that we can instantiate to create Sprite objects, right? Well no, maybe it's because each game is going to have its own need when it comes to sprites, or maybe they're going to be added later to the XNA framework, but there isn't an actual Sprite class definition in XNA.

    Texture2D Objects

    Texture2D objects store images. Sprites are just images drawn on the screen, so the images that are drawn on the screen are stored in Texture2D objects. Typically you will create an image in a drawing program such as Photoshop, GIMP, Paint.NET, or even Paint, and load the image from the file into the Texture2D object.

    The Content Manager Class

    The ContentManager class is a key component to any XNA game. It handles the loading and management of the graphics content and the content pipeline. The content pipeline is what is used at design time (the time when you're writing the game) to easily bring in content assets created with other tools (MS Paint, Photoshop, 3D modelers,sound files, etc) and get them into a format understood by XNA and ready for packaging. 

    The SpriteBatch Class

    The SpriteBatch class is the key to sprite handling in XNA. To draw sprites, the following steps must be taken.

    1. Call Begin() on the SpriteBatch object.
    2. Call Draw() on the SpriteBatch object one or more times.
    3. Call End() on the SpriteBatch object.

    It is important to note that in XNA, performance is more closely tied to how many SpriteBatch Begin() and End() calls are made per frame and not how many Draw commands are called. So if you can do all of your drawing in one SpriteBatch, that is ideal. There are cases where you won't be able to do this, and we'll cover those in a future lesson.

    Let's Draw a Sprite

    In most programming languages, the first sample program is traditionally a "Hello World" program. In C# when building a Windows Forms application, the code will look something like:

    MessageBox.Show("Hello, World!");

    In graphics and game programming, it seems that the first program is typically displaying a ball on the screen and then animating it. So I won't break with tradition. Let's draw a ball.

    First we need an image. Save this image to your computer by right clicking and selecting "Save Target As..." or "Save Picture As..."

    All graphics and sound assets go in a special folder in your project. This folder is the Content folder. Right click on the Content folder in the MyFirstGame project in the Solution Explorer and select Add->Existing Item. Navigate to where you saved red_ball.bmp. Select it and click OK. The image is now part of your project and in the content pipeline. If you right click on red_ball.bmp in the Solution Explorer, and select Properties, you'll see some of the information that the content pipeline needs to process this file. Notice that the Asset Name is "red_ball". This is the name that we will use when referring to this image in the program. Also note that the asset name strips off the ".bmp" file extension.

    Now as I said above, we need a SpriteBatch object in order to draw a sprite. We also need a Texture2D object to store the image data in until we need it.

    Since we are going to need these objects repeatedly during the game, it makes sense to define them as variables in our Game1 class definiton. Variables defined as part of the Game1 class definition can be accessed from any of the Game1 methods.

    Below the lines in the file that look like this:

    public class Game1 : Microsoft.Xna.Framework.Game
    {

        SpriteBatch spriteBatch;

    Add the following:

    Texture2D spriteTexture;

    Notice that the SpriteBatch declaration is added for you. In Version 1 of XNA, you would have had to declare this yourself, but it was so common that they decided to help out a bit. This new line adds a Texture2D named spriteTexture to the Game1 class definition. Whenever we want to access either of these variables from a Game1 object, we will specify them by name. Now we need to instantiate these objects. Since they are graphics objects, we initialize them in the LoadContent method. So in the LoadGraphicsContent metod, right after the

    // TODO: use this.Content to load your game content here

    statement, add the following:

    spriteTexture = Content.Load<Texture2D>("red_ball");

    The Content object is an instance of the ContentManager class. The added statement calls  a method of the Content object in order to load a new Texture2D object from an image file. The asset name is being passed as an argument to the method. An argument is data that is passed to a method to help it do its job, or sometimes the data contained in the argument is modified by the method.

    This tells the ContentManager that we're loading an image, and the "red_ball" argument is the asset name of the content we are trying to load. The asset name is a string. Strings contain text values. In this particular case, we are passing a string literal also known as a string constant. String literals are always wrapped with double quotes in C#.

    Now that we have created our spriteTexture object, scroll down to the Draw() method and add the following after the line

    // TODO: Add your drawing code here

    spriteBatch.Begin();
    spriteBatch.Draw(spriteTexture, new Vector2(0f, 0f), Color.White);
    spriteBatch.End();

    So as stated previously, we need to begin our sprite batch, draw, and then end our sprite batch. To call a method of an object, specify the variable name for the object, followed by a period (.), followed by the method name to execute.

    For the Draw method, the arguments we pass to the method are the Texture2D object to draw, in our case it is the object named spriteTexture because this is what we defined it as at the top of the class definition, then the top left corner of the location to draw the sprite to (0f, 0f) is the upper left corner, and then the color to draw it with. If you draw with Color.White, the drawn sprite will be the same color as the original image. If you specify a color other than white, the drawn sprite will be tinted based on that color. 

    Build the program and run it again. You should see the red ball in the upper left corner.

    So why doesn't it have a magenta square around it? By default, XNA "masks out" any pixels that are pure magenta (full red and full blue color with no green). You could also use an image that supports transparent backgrounds, such as a PNG file. Here is an example of the same image as a PNG file with a transparent background:

    If you were to delete the red_ball.bmp from the solution and add red_ball.png, you would get a similar result as previously. One advantage to using an image in PNG format is that you could have parts of the image that are partially trasparent. This is useful for creating smooth edges around an image (known as anti-aliasing), as well as other effects. When drawn, the background behind the sprite would show though based on how transparent the image is.

    Posted: Oct 09 2008, 11:52 by Bill Reiss | Comments (7) RSS comment feed |
    • Currently 3.166666/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under:

    Lesson 2: Our first look at the code (Part 2)

    So in the last lesson we saw a lot of the plumbing involved in referencing other namespaces and assemblies, creating our own namespace, and commenting the code. This lesson is all about classes and objects.

    Classes and objects are at the core of C# programming and modern programming in general. Rather than spend a lot of time duplicating the explanations of people more knowledgeable than myself on the topic, here is a link to a detailed article explaining objects and classes in C#:

    http://www.csharphelp.com/archives3/archive497.html

    Classes and objects are a complex topic with a lot of subtleties, so for simplicity's sake at this time, I will make some statements that are not entirely correct but are good enough for now. 

    Briefly, objects are a set of data and behaviors that are grouped together. Classes are templates where we describe the data and behaviors of the object. Classes do not actually store any data or execute any code. Objects are instances of classes and each object has its own data. We refer to the code associated with a particular class as the class definition. In our Game1.cs file, we have a class definition for a class named Game1. Since our class is inside the namespace definition "MyFirstGame", the fully qualified name of the class is MyFirstGame.Game1.

    Class definitions contain variables, methods, and properties.

    Variables are instances of other objects or primitives. They contain your data.

    Methods are your object's behaviors. You tell your object to do something by calling a method.

    Properties are characteristics of your object that other objects can see.

    Our Game1.cs file was generated with 6 method definitions. Let's take a look at these one at a time.

    public Game1()

    This is a special method called a constructor. It is called when an object is first created. It typically will run some code which initializes the data in the object variables and do some other setup work. We will leave this method alone and do our setup code in the Initialize() method below.

    protected override void Initialize()

    This is where you can run some code to set up objects for your game.

    protected override void LoadContent()

    This is where we will load all of our graphics and sound related data. We'll cover this in more depth later.

    protected override void UnloadContent()

    The opposite of the LoadContent method, we can use this to clean up.

    protected override void Update()

    The Update method is executed on a periodic interval and is where you will put code to calculate the position of your game elements, update the score, set other data values, check for mouse, keyboard, or game controller input, etc.

    protected override void Draw()

    The Draw method is where you will put code to draw your game screen. It is also called on an interval and each time it is called you will draw the entire game surface to reflect the current state of your game. Each time Draw is called, you are drawing a single frame, similar to how a cartoon is made up of frames or cells that are each drawn individually.

    Notice the following line of code in the Draw() method:

    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

    This statement is what set the background of our game surface to blue.

    Try deleting the ".CornflowerBlue" text. Then type the period (.) again. You should see something that Microsoft calls IntelliSense. Intellisense gives you hints on the available values when possible so that you don't have to go look up the valid values every time. Select "Black" from the list. The code should now look as follows:

    graphics.GraphicsDevice.Clear(Color.Black);

    Now if you run the program again, it should have a black background instead of a blue background like this:

     

    The Update() and Draw() methods are where most of your work is going to take place when writing a game. Try to keep only drawing code in the Draw() method and everything else in the Update() method.

    Posted: Oct 09 2008, 11:21 by Bill Reiss | Comments (1) RSS comment feed |
    • Currently 4.857143/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under:

    Lesson 1: Our first look at the code (Part 1)

    A good way to start learning how to program is to look at examples of code and see how they work. In our MyFirstGame project, XNA and C# Express generated some code for us to get us started. Let's take a look at some of this code to get some idea of how it works.

    viewcodeMost of your work actually adding game logic will be done in Game1.cs or in other files called from Game1.cs. The .cs file extension stands for C# (C-Sharp) and all of your C# code will have that extension. To view the code, find Game1.cs in the Solution Explorer pane and right click on it and select "View Code". You can also select it and click on the "View Code" icon in the Solution Explorer toolbar.

    Now there are a few things about the format of C# code. First of all, code is broken down into statements and blocks, with statements being a single "line of code" and blocks grouping together a series of statements, sometimes with conditional logic controlling whether the block will be executed. I put "line of code" in quotes because in C# it technically does not correspond to a single line in the file, it includes all of the code up to the semicolon. A statement can be separated over many lines in the file. In C#, blocks start and end with a curly brace, "{" to start a block and "}" to end a block. In C#, all code is case sensitive. The editor will try to fix your capitalization for you if possible, but it is something to look out for.

    So at the top of our Game1.cs file, we have a series of using statements. These tell C# that there are other namespaces of code that we will be referencing from the code in this file. A namespace typically contains code which is related in some way, either sharing characteristics or used together to accomplish a task. Namespaces are used to avoid naming conflicts between different pieces of code. I will dive deeper into namespaces in a later lesson.

    So after the using statements, we have our own namespace defined, and then all of the rest of the code in the file is within the namespace's block. As stated above, this helps to avoid avoid naming conflicts and is generally a good thing to do. If you start creating your own assemblies, (libraries of code that can be used in multiple projects), using namespaces is a necessity, and you need to be careful about how you name your namespaces. For now, just leave it as it is.

    It's a good idea to comment your code. Comments are where you can explain what a certain piece of code does, or anything unusual related to a piece of code. It can also be used as a placeholder, like

    // TODO: Add your initialization logic here

    In C#, anything after a double slash "//" until the end of the line is considered a comment. Comments are not compiled into the program and are stripped out. Comments not only make it easier for others to understand your code, but also help you out if you haven't looked at the code for a while and are trying to remember how it works.

    In Game1.cs, you will see a triple slash "///" comment. This is a special comment which can be used to generate documentation automatically about your code. There are tools that can convert these special comments to web pages or other help formats.

    Posted: Oct 09 2008, 10:32 by Bill Reiss | Comments (1) RSS comment feed |
    • Currently 4.5/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under:

    2D Vs. 3D Games

    Update: Note that Zune XNA games only support 2D graphics, so that's another reason to focus on 2D for a bit.

    2D games include the classics like Pac Man, Defender, Galaga, Donkey Kong, Super Mario Bros, etc.

    3D games include Doom, Quake, Halo, etc.

    XNA supports both kinds of games. Generally I think it's easier to put together a 2D game, so that is what I'll focus on first. Also, most 3D games require at least some 2D graphics, such as a score or a health meter display.

    Now I just need to get on my soapbox for a second. In my opinion, gameplay is king. You can have the best looking 3D rendered game but if it isn't fun to play, what's the point? Focus on gameplay first. Nintendo is banking on this for their new Wii console. The graphics are not going to be nearly as impressive as the XBox 360 or PS3 but they are banking on their games being more fun to play.

    Posted: Oct 09 2008, 10:21 by Bill Reiss | Comments (11) RSS comment feed |
    • Currently 4.333333/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under:

    Getting Started with XNA 3.0 and C#

    Welcome. Game development is near and dear to my heart since that is how I first learned to write software in the early 80's. Game programming and programming in general have come a long way since then. I hope that I can inspire others to learn to program by developing their own games and that I can give some assistance to you along the way.

    XNA Game Studio Express (from now on I'll probably just write it as XNA) is an exciting offering from Microsoft. It allows developers to create fully functional Windows, Xbox, and Zune games using the latest and greatest development environment available.

    Here's what you'll need:

    First, download and install Microsoft Visual C# 2008 Express with SP1 (any Visual Studio 2008 SP1 will work as well). You can find it at this link: http://www.microsoft.com/express/vcsharp/

    Once that's installed, you can download and install XNA Game Studio 3.0 from here: http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-9883-9A33C0AD8FEE&displaylang=en

    You should now have a new program group in your start menu, titled "Microsoft XNA Game Studio 3.0" and a shortcut under there for either Visual Studio or Visual C# Express 2008. Launch the development environment from that shortcut.

    You should see a screen like the following:

    newproject

    Select File->New Project. You should see a list of installed templates. Select Windows Game (3.0). In the Text Box at the bottom of the dialog, enter the name of your game. Let's call it MyFirstGame. Click OK. This will generate a project and create the base code for the game. It is actually a working application, but it doesn't do very much. If you click the green "Play" button in the top toolbar you can see what it does. It should look something like this:

    Congratulations, you have created your first working program! Next time we'll start to make it do something.

    Posted: Oct 09 2008, 06:18 by Bill Reiss | Comments (8) RSS comment feed |
    • Currently 2.230769/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under:

    Relaunch of XNA 101!

    Over the past year and a half or so, I've been asked a many times to update my samples on XNA 101, and it just seems like I've always been distracted with other stuff. With the new announcements about writing Zune games in XNA, and selling games on Xbox 360, I thought it would be a good time to finally bring things up to date.

    Over the next few weeks, I'll be updating the old tutorials bringing them up to XNA 3.0 Beta, and updating the sample code as well. I'll post the updated entries here as they become available.

    I'm also hopeful that controlling my own blog server will help to make things more interactive.

    Posted: Oct 09 2008, 06:16 by Bill Reiss | Comments (3) RSS comment feed |
    • Currently 5/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under: