Download and unzip the zip file and you will see an
ExampleProgram
folder. Open the
ExampleProgram
folder, the
EXE
folder contains the compiled program and you can double click on the
.sln
file to work with the source code.
In order to do anything with the game that has been , you'll need to edit the
program, using Microsoft Visual Studio. As of this writing, you can use
either Microsoft Visual Studio Professional Edition, or the freely downloadable
Microsoft Visual C# Express Edition. Once you've got Visual Studio
installed, you'll need to install the extra XNA stuff. Instructions for
doing this can be found elsewhere, so we won't repeat them here.
Please ask your instructor which software packages you should use, if you
haven't already been told.
No matter which version you installed (Visual Studio Pro, Visual C#, etc,
etc), these instructions will refer to the software as 'Visual Studio'
If you're provided with a starter project (or if you just finished the
tutorial on how to create your own XNACS1 game, starting from a normal, basic
XNA program), the you'll have a number of files, contained in a couple different
directories.
In order to do anything with the game, you'll need to edit the program, using
Microsoft Visual Studio. You start editing a program similar to the way that you
would start editing, say, a Microsoft Word document:
Find the file you want to edit, double-click on it, and Microsoft Windows
will figure out that you want to edit it with Visual Studio, then start Visual
Studio, and tell Visual Studio which file to edit.
A different option is to start Microsoft Visual Studio, then tell Visual
Studio to open the file you want to work with. Just like in Word, you'll
use the File menu. However, since you want to work with an entire
project (which is composed of multiple files), you'll want to use the File
→ Open Project menu option, instead of the normal
Open File option.
If you want to edit the program by
double-clicking on a file (perhaps one that you found in My Computer), then
you'll need to follow these steps:
First, you need to find the file that you want to work with. It's
preferable to find the file whose extension is .SLN, and is identified as a
Microsoft Visual Studio Solution file. By default, however, Windows
doesn't show you the file extension for your files, which can make it a bit
more difficult to identify the file correctly. Follow the instructions
in the following box to get windows to show you the file extensions:
What to do if you can't see the file extension (
Windows
XP
)
Start up your normal file-browsing tool, such as My Computer
Select the Tools
→Folder Options menu
item.
In the dialog box that pops up, you
want to select the 'View' tab at the top, and then UNcheck the 'Hide
extensions for known file types' (this second item will be towards the
bottom of the screen), as pictured here:
(While you're at it, you may want to check/uncheck items so that
it matches the above - this way, you'll be able to see more
information about what's stored inside your computer)
Finally, click OK
What to do if you can't see the file extension (
Windows
Vista
)
Start up your normal file-browsing tool, such as My Computer
The next step is, just like with WindowsXP, to select the Tools
→Folder
Options menu item on the menu bar. However,
Vista will
normally hide the menu bar, so it's not visible. You can get
around this two ways. First, if you press the 'Alt' key, then
Vista will temporarily show you the menu bar, and then you can select
the Tools
→ Options from there.
Second, if you want to permanently display the menu bar, you can open
up something like Start→Computer, and then click on
Organize→Layout→Menu Bar, as pictured here:
In the dialog box that pops up, you
want to select the 'View' tab at the top, and then UNcheck the 'Hide
extensions for known file types' (this second item will be towards the
bottom of the screen), as pictured here:
(While you're at it, you may want to check/uncheck items so that
it matches the above - this way, you'll be able to see more
information about what's stored inside your computer)
Finally, click OK
Once you've found the .SLN file, you can simply double click on it, which
will open up Visual Studio for you, and automatically load in the right
Solution/Project for you.
Note that in many/most cases, you can also double-click on the file that
ends in .CSPROJ (this file may be in a subdirectory under the .SLN file).
HOWEVER, if you happen to have multiple versions of Visual Studio installed,
double-clicking on the .CSPROJ might not work - Windows will get confused as
to which version of Visual Studio it needs to start up.
If you want to edit the program by first
opening Visual Studio, then you'll need to follow these steps:
Normally, it's easier to find the .SLN file and double-click on that, as
explained above. However, one common use for the 'open a program from
within Visual Studio' scenario is that you already have a solution open, and
you want to switch to different program. In that case, you probably want
to first close the solution that you're currently working on, by using the
File
→Close Solution menu item. After that,
you'll use the File→Open Project item to open the .SLN file (which you'll need
to find). Conveniently, Visual Studio keeps a list of list of recently
used projects in the File→Recent Projects submenu, so once you've opened a
project, you can quickly and easily reopen it. All of these options are
pictured here:
Once you've opened the Solution/Project, you
can now compile and run the program/game:
If you're given a starter project, you don't need to add anything (that's
XNA specific) in order for things to work, so you should be able to go
straight to the next step, and compile-and-run the game.
If you've done the 'Creating Game-Themed Applications From Scratch'
exercise, then you know how to add the XNA-specific fonts and dynamic link
libraries in order to make a normal, basic XNA game into an XNACS1Lib game.
If you haven't done that, and you're curious about how that's done,
there are directions here
.
Next, you need to compile, and then run your program. Handily,
Visual Studio will do both of these steps for you when you select the Debug
→Start
Debugging option. It will also do both steps when you select Debug→Start
Without Debugging, but for video game programs, getting used to using the
Start Debugging option is probably best. Both options are pictured
below:
(If you're also writing Console applications, you'll want to use the Start
Without Debugging option for your
Console
applications),
If you want to first compile your program (without immediately running
it), you can do so using the Build
→Build Solution
menu option, as pictured below. This is useful for getting a list of
compile-time errors (i.e., a list of syntax errors), if that's what you're
looking for. We'll look at syntax errors later on.
Normally, the provided starter project should compile just fine, and
should run.
There may be times when your instructor gives you a project that doesn't
quite compile; in that case part of your job is to figure out why it doesn't
compile, and fix it.
There may also be times when the game crashes when you run it.
Again, part of your job is then to figure out why it crashes, and to fix it.
If you're really having trouble, feel free to ask your instructor for
help, but be aware that you
More commonly, the game will compile just fine, and run just fine, but
probably won't do a whole lot. The assignment/exercise/etc should offer
suggestions about what the game should do, and you should then figure out what
needs to happen in order to make the game do that (and then you should
implement what you need to / are required to in order to make that happen)
Notice that the game provided in the example code doesn't really do much
right now - that's fine, right now all we want to look at is the basic parts
of the source code, before we go adding in anything that actually makes this
into a game.
Let's start by looking at the various files in your application, and
explaining what they do. You should look at these both in Windows (using
My Computer, or the Windows Explorer, or whatever else you like to use), as
well as in Visual Studio. You should do both so that you're aware of
where things are stored on the hard drive (in case you need to
find/copy/move/backup them), and so that you're aware of how Visual Studio
sees things.
In order to view the files in Visual Studio, you should activate to the
Solution Explorer panel.
You can do this by using View
→
Solution Explorer:
.
Once it's visible, then you should see it
along the right edge of your screen:
Now, let's look at each file, and a brief description of what it does, using
the above picture as a guide. The files that are particular important, and
that you'll use frequently (inside or outside of Visual Studio) are
highlighted like this
.
Folder/File
(in Windows)
Location/File
(in Visual Studio's Solution Explorer)
Purpose
SimpleXNA.sln
Solution 'SimpleXNA' (1 project)
(this is the top line in the Solution Explorer)
.sln - this is the
solution
file. This can contain multiple
projects
(see the .CSPROJ
entry below for more on projects)
You will frequently use this file to
start Visual Studio
SimpleXNA.suo
<not visible in the Solution
Explorer>
.suo - this is
data file
that Visual Studio uses.
It's a temporary file that Visual.Studio uses to store information it
has generated from the other files, so we will not change this file
directly.
Note:
Your instructor may ask you to delete this file before
turning in your homework, since it takes up space, and yet Visual Studio
will automatically generate it from the other files in the solution.
SimpleXNA
/SimpleXNA.csproj
SimpleXNA
(it's the line that's
immediately underneath the
Solution 'SimpleXNA' (1 project) line)
This is the
project description
file for the
.sln
solution file. In general, a solution (one .sln file) can consist of
many different projects (many .csproj) files. Each project might
be a separate program, that are all related to the overall solution.
For example, 1 project might be a game that we're making, another
project might be the installer program that will install our game onto
customers' computers
SimpleXNA
/
Properties
/AssemblyInfo.cs
Properties
/AssemblyInfo.cs
Description for the project, e.g., name to appear on the
window title bar.
Note
: Technically, your program (your game) can still be
compiled even if this file is missing, by removing this file from the
project. HOWEVER, you should make sure that you hand this file in,
since it will make it easier for your instructor to quickly and easily
grade the assignment.
<not visible in Windows>
References
This is a list of
D
ynamic
L
ink
L
ibraries - files that contain code that extend the C#
language to do new things. You can't directly see this in Windows
because these are really a list of references to already existing files
(think of them as being like hyperlinks to existing files).
What these files do:
Microsoft.Xna.Framework
, and
Microsoft.Xna.Framework.Game
DLLs make it possible for our C#
program to use functionality built into XNA.
The
System
and
mscorlib
libraries together provide
the 'basic' functionality of the
.Net
Framework Class Library.
The
XNACS1Lib
, provides all the extra functionality (on top
of XNA) that we'll be using in these exercises and tutorials here.
SimpleXNA
/
Content
/Content.contentproj
Content
This is the content project description file. Fonts,
file texture images, and audio wave files are examples of
contents
.
We will need to describe how these contents will integrate into our
project via this
"
content project".
Note
: You normally won't really need to do anything with these
files. If you're creating a game on your own, you may want to add
a new font, or new images, and those sorts of things would go into this
directory.
<not visible in Windows>
Content/References
Much in the same way that the overall References folder
contains additional DLLs that extend the C# language to use things like
XNA, this folder contains additional DLLs that extend Visual Studio
itself. In particular, these libraries are used in the 'compile'
phase, in order to take something like the Arial.spritefont file, and
process is so it can be included the game's executable file.
<not visible in Windows>
Content/Resources/Fonts/
Arial.spritefont
This contains a definition of the Arial font, which the
XNACS1Lib requires in order for the game to run.
<not visible in Windows>
Content/Resources/Textures
< This is not present in the above picture.>
This
folder contains any graphics that you want to display during the game.
Allowable image types are listed
here
, but you may have different results, based on the exact version
of XNA that you're using.
SimpleXNA
/
Content
/
bin
and
obj
<not visible in the Solution
Explorer>
Build results from the content-related compile phase of
creating the game.
Note:
The directories, and everything in them, are generated
from the other files in the solution, similar to the SimpleXNA/bin and
SimpleXNA/obj directories, above
Note #2
: Because these files can take up a fair amount of
space, and because these files are generated from other things in the
solution, your instructor may ask you to delete these directories before
handing them in.
SimpleXNA
/Game.ico
Game.ico
This is the graphical icon on the title bar of the running program.
SimpleXNA
/Game1.cs
(this is in the SimpleXNA directory, and the file is
named Game1.cs)
Game1.cs
This file contains the
Game1
class. This is the main file we will work with. It contains almost
all the C# source code that we'll use in our game; you change your game
by editing the source code, and then telling Visual Studio to re-compile
the source code into a program (into a game), and then running that
program (game).
You will frequently use this file to edit your game. You will
use this file more than any other file, most likely.
NOTE:
The name of this file
may be different from what you see here
- it may or may not be
Game1.cs exactly. To find this, look for a file ending in .CS that
isn't the Program.cs, nor the AssemblyInfo.cs.
Note #2
: A program can actually be stored in multiple .CS
files (normally 1 class goes into each file), in which case you'll see
multiple .CS files, possibly located in subfolders (you'll see the same
subfolder in both Windows and Visual Studio)
SimpleXNA
/GameThumbnail.png
GameThumbnail.png
This
is the graphical file for representing this game on the XBOX 360
console. By default, this looks like a some circles
SimpleXNA
/Program.cs
Program.cs
If you open this up, you'll see that it's very short,
and almost identical for every game you'll work with.
The purpose of
this file is to start the program, by loading the Game1 class, and
telling it to run.
Normally, you'll never need to look at this file, nor will you need
to change it.
SimpleXNA
/
bin
and
SimpleXNA
obj
<not visible in the Solution
Explorer>
Compile result. As the names suggests,
obj
contains the compile object files, while
bin
contains the
executable binary files.
Note:
The directories, and everything in them, are generated
from the other files in the solution. For example, when Visual
Studio compiles the source code into an actual program (an actual game),
Visual Studio will put the store the program in files in these
subdirectories.
Note #2
: Because these files can take up a fair amount of
space, and because these files are generated from other things in the
solution, your instructor may ask you to delete these directories before
handing them in.
If the source code (.CS) files
aren't open when you open the project, you will need to open them inside
Visual Studio. You can do this by using the Solution Explorer, then
double-clicking on the Game1.CS file.
Since this is the file that you'll spend most of your time editing, let's
look at it in more detail:
First, let's examine the 'using' statements at the top. When you
open the file, and scroll all the way to the top, you should see:
using
System;
using
System.Collections.Generic;
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.Net;
using
Microsoft.Xna.Framework.Storage;
using
XNACS1Lib;
As it turns out, all those .DLLs in the
References
directories
contain a lot of code. The using statements allow us to specify which
parts of those .DLLs we actually want to use in this particular program.
It's also a way to allow multiple software companies to give the same
name to their pre-fab code, and yet still allow you to use all that code in
your program/game. We won't go into this here, but it's good to be
aware of, in case you need that functionality later on.
All of these using statements MUST go at the very top of the file (even
above the namespace declaration, which comes next);
Don't forget that the semi-colon (
;
) at
the end of the line is required - you'll get a compiler error if you remove
them.
The first two statements (
using
System;
, and
using
System.Collections.Generic;
) are common to all C# solutions, whether
or not they use XNA (The
using
System.Collections.Generic;
was added in Visual Studio 2005 - older programs may not have that
line, and most of the programs that we'll be writing here don't actually
need it, either).
All the statements that start with '
using
Microsoft.Xna.
' specify various bits of functionality in XNA that
we'll need for our game. For now, feel free to read through the list,
don't worry about the details of these - this will be 'boilerplate' text
that you'll see with each program.
Finally, the
using
XNACS1Lib;
statement tells Visual Studio that we'll be using the
functionality built into the custom XNACS1Lib.DLL. We need this to
access the material that we'll be making use of in these tutorials and
exercises.
Next, you'll see the namespace declaration:
(the using statements are grayed out so they don't distract you, but present
so you know where this new stuff is located in relation to the stuff we were
just looking at)
using
Microsoft.Xna.Framework.Net;
using
Microsoft.Xna.Framework.Storage;
using
XNACS1Lib;
namespace
SimpleXNA
{
The namespace declaration basically creates a 'bucket' in which we'll put
all of our code. We can choose pretty much any name we want, but be
aware that changing the name after you've created the project may be tricky
(there are number of things that have been configured to use the name
already).
As a side note: if someone else wanted to use the code that we'll be
creating here, they'd have a line that reads '
using
SimpleXna;
' amongst their other 'using' statements.
Note that right below the '
namespace
SimpleXNA
' line, there's an open curly brace (
{
). This tells C# (and you!) where the namespace begins. You'll
find a matching close curly brace () near the end of the. One possible
source of errors is mismatched curly braces, which you'll need to get good at
finding and fixing, so practice finding each curly brace's match now.
Possible sources of mismatched braces include not having enough braces,
having too many, or having them in the wrong location(s).
Next up is the class declaration:
namespace
SimpleXNA
{
///
<summary>
///
This is the main type for your game
///
</summary>
public
class
Game1
:
XNACS1Base
{
Immediately above the class are some
comments
. On each line,
everything after the /// is ignored by C#, so we can write whatever we want
to on that line. We'll see more about this in future tutorials.
The actual line that we're looking at, '
public
class
Game1
:
XNACS1Base
', is
actually mostly boilerplate. While it's nice to know what's going on, be
aware that you normally won't hand-edit these lines for a long time.
Looking at the rest of the line, we see the word
public
, which tells C# that
anyone can use the block of code that we're about to write. Since we're
not going to reuse the code in another game, it actually isn't that important,
but it's probably good to get in the habit of putting
public
there, so that it will be
a natural reflex by the time you do start reusing code.
The phrase
class
Game1
says that this is a new chunk of source code named Game1. You'll
notice the open-curly-brace on the line below it, and you should find the
matching close-curly-brace near the end of the file.
The phrase
:
XNACS1Base
says that
our Game1 will built off of another chunk of code that was named XNACS1Base.
If we don't include this, then we can't use any of the nifty features in the
XNACS1Lib.dll.
Remember that C# is case-sensitive, so you need to type
XNACS1Base
, and NOT
XnaCs1Base, nor xnacs1base, nor XnAcS1BaSe, nor anything else.
Handily, Visual Studio will color-code words that it recognizes, and since
XNACS1Base
is defined
in both a .DLL that the solution references, and we've told Visual Studio that
we're using that code, Visual Studio will color-code
XNACS1Base
when we get it right.
Because this is how the program works (how the game works), actual
on-screen animation (for example, a hero moving across the screen) is done in
a way that's similar to '
flip-book
animation
' - we'll draw the hero on the screen, then update our data
structures so that the hero is moved over, slightly. Then we'll draw the
hero in the new, slightly moved over location. Then we'll update our
data structures to move the hero over a little more. Then draw the hero
in that new location again.
With the XNACS1Lib, your game will do this as many times as possible per
second. Given a simple game, it's very common to go through the Draw
→Update
cycle 30 or more times per second
If your code gets 'stuck' for some reason
(maybe your Update or Draw logic is stuck in an infinite loop, for example),
you'll see that the game 'freezes', and stops drawing on the screen.
This is because your code is stuck in one of the two steps in the cycle, and
NOT repeatedly drawing on the screen. This is good to know - if you see
this symptom (the screen of your game is blank, and/or the game is frozen),
one possible cause is that your code is stuck somewhere.
There are multiple ways to initialize different parts of the game, and as
these tutorials progress, you'll see more about them, and what to use them for.
For now, we're going to look at the InitializeWorld method, and how it defines
the coordinates of the lower-left hand corner of the screen, the width of the
screen, and (by implication) the height of the screen.
InitializeWorld():
During InitializeWorld, we allocate any
additional memory our game needs, and set up everything so that our game is
ready to draw something on the screen (in the above pictures, we drew rectangles
on the screen - InitializeWorld is where we would set the center position,
width, and height of the rectangles). Even though we're not drawing
anything on the screen right now, we still need to define the coordinate-space
used by our game, like so:
protected
override
void
InitializeWorld()
{
World.SetWorldCoordinate(
new
Vector2
(0,0),
100.0f);
// Sets lower left
corner and the width of the drawing area
}
Inside the open curly brace (
{
} and the closing curly brace (
}
}, you see a single command:
SetWorldCoordinate(
new
Vector2
(0,0),
100.0f);
This line actually calls
into the SetWorldCoordinate functionality that's provided by the XNACS1Lib,
and is given two parameters.
The first parameter consists of everything between the opening (, and the
first comma - '
new
Vector2
(0, 0)
'.
This provides the coordinates of the lower-left hand 'origin'
We can move the origin to somewhere else, but normally we'll keep it at
(0,0) to make calculations easy.
Except for the fact that you can choose what the coordinates of the
lower-left hand corner of the screen are, the coordinate system for
XNACS1Lib works just like it did in your math class(es). For example,
if we choose (0,0) to be the lower-left corner (as we normally will), we'll
get a picture that looks like the one below. We normally write
coordinates in (X,Y) format, where X is the number of units towards the
right we want to move over, and Y is the number of units towards the top
that we want to move up. For example, (10, 5) is 10 units over, and 5
units up, just like in math class. Here's a picture to help make this
clear:
Second parameter is everything between the comma, and the closing ) that
matches the open parenthesis - '
100.0f
'.
This is how many units wide we want the window to be. Note that the
window's width on the screen will be set automatically so it fills up as much
of the screen as possible, so what you're really choosing here is the scale
for your window. If you choose 100 units wide, then you can thing about
a coordinate (such as 10 across, and 5 up) to be 10% of the way across the
screen. The height is automatically calculated so that the proper aspect
ratio is maintained. To recap:
We can choose this number arbitrarily
Example: If we use 100 for this , and putting something 20 units towards
the right means that it's 20% of the way across the screen
The size of the window itself (measured in pixels, or inches, or
centimeters, whatever you want to use) is chosen by the
XNACS1Lib, and is normally set to be about 90% of the width of your
computer's monitor.
Let's look at a couple of examples, without worrying about the C#
source code.
Let's say that we choose (0,0) for the lower-left corner, that we choose
100 as the width of the screen, and that we put a rectangle in the
middle of the screen. The rectangle's side will have a length 10
for both height and width. When we run the program, the coordinate
(0,0) should be at the bottom left corner, (100, 0) should be in the
bottom-right corner, and if the game calculates the height of the window
to be 56.27572, then the top-left corner should be (0, 56.27572) the the
top-right (100, 56.27572), like so:
What if we put the same rectangle so that it's center is at (5,5)?
Since the rectangle is
10 units wide
, and since we're positioning
the
middle of the rectangle
, there should be 5 units between the
middle and the left edge of the rectangle, and 5 between the center &
the right edge. So by putting the middle of the rectangle 5 units over,
we would expect the rectangle to line up exactly with the left vertical
edge of the screen, and fall a little below the bottom edge of the
screen. The coordinates of the corners won't change, but the
location of the rectangle will, like so:
Now, what if we change the origin of the lower-left edge of the screen
to (5,5), by changing InitializeWorld to look like:
protected
override
void
InitializeWorld()
{
World.SetWorldCoordinate(
new
Vector2
(
5
,
5
),
100.0f);
}
When we run the program, the coordinates of all the corners should be
moved over by 5 and up by five. (5,5) should be at the
bottom left corner, (105, 5) should be in the bottom-right corner, and
if the game calculates the height of the window to be 56.27572, then Y
value of the top edge should be 56.27572 + 5 = 61.27572, and therefore
the top-left corner should be (5, 61.27572) the the top-right (105,
61.27572), as pictured below.
Notice also that the bottom-left corner's coordinate is now in the
middle of the rectangle, whose center is still at (5,5):
You'll notice that in both examples, the height of the screen was
automatically calculated for us, based on the width of the screen, so as
to keep the aspect ratio correct.
Normally,
the UpdateWorld methods would be full of code. In fact, most of your time will spent
either in these locations, or else in other places in the code... that were
called from UpdateWorld. Right now it's nearly empty since our
start project isn't really doing anything.
UpdateWorld():
protected
override
void
UpdateWorld()
{
if
(GamePad.ButtonBackClicked())
this
.Exit();
}
Anything that we want our program to do goes here. This
includes responding to the user's/player's input (did the player just push
the 'A' button?), adjusting the game (since the player pushed the 'A'
button, the on-screen hero should now jump)(another change might be to move
everything a little bit, as per the flip-book animation) (another change
might be to adjust the score, if the player picked up a prize in the
game)(etc)
You'll notice that there are two lines of code in UpdateWorld right now.
In a nutshell, we want the game to exit (to stop) if the player pushes the
'Back' button on the XBox controller, or the equivalent to the 'Back' button
on the keyboard. The first line,
'
if
(GamePad.ButtonBackClicked())
',
is the way we ask (in C#) if the Back button has been clicked/pushed.
The second line, which only gets run if the first line detects that the Back
button is, indeed, clicked, simply says for this game (i.e., the current
game) to exit.
Look at this, but don't worry about it - we'll spend the rest of these
tutorials looking at details like these :)
Note that right now, we've told the game to do (almost) nothing, so nothing is
happening
KEY IDEA: The computer does
exactly what we tell it to
. No
more, no less. Not what we want, not what we meant, but
exactly
what we told it to do.
Note:
To work with the
XNACS1Lib
Library, a bare minimum project must include:
Fonts: the
Arial.spritefont
must be part of the project
The XNACS1Lib_PC.dll must be included as a reference
2 functions:
InitializeWorld():
allocate memory and initialize instance
variables, and define the window drawing coordinate.
UpdateWorld():
poll user input and update application state.