I can hardly sit still when there is
new technology out there to explore, and even though the shrink-wrap
is barely off of .NET 3.0, the wannabe game developer inside of me
has been screaming to try out XNA. With the Christmas break
affording a lull in the rather bland coding of my recent projects, I
was finally able to give it an ample “go”.
I just love the iambic feel of saying
“The holidays and XNA!”
What is XNA?
XNA is an API to make it easy to
develop games for both the PC and the Xbox 360. (You should note
that the official
FAQ's state that XNA does not actually stand for anything.)
Additionally, Microsoft has provided XNA Game Studio Express (GSE)
which is a special version of Visual Studio Express (C# only). It
has some nifty features like being able to publish your code to an
Xbox 360.
XNA Game Studio Express is free. You
can download and start making games for your PC immediately.
However, if you want to write games for your 360, you will need to
purchase a subscription to the XNA
Creators Club (that's another $99/year).
Another interesting thing to note is
that XNA does not include support for networking. That means you cannot write 360 games that are Live enabled. If you are
targeting Windows, you still have access to all of the .NET framework
and there is nothing to stop you from writing your own multiplayer
code for the PC. (I haven't tried it yet, but I don't see why you
couldn't use WCF in an XNA PC game.)
The XNA framework is really to
successor to managed DirectX, but it is much more accessible that
than the previous release. Additionally, the the framework and Game
Studio Express employ the concept of a Content Pipeline which eases
the integration of art assets into the game.
How Does It Work? Or XNA 101 for the Business
Developer
Guys like me are accustomed to
thinking about applications from an event-driven (and hopefully)
object-oriented perspective. Game programing is different, and it
takes a paradigm shift. (I can't believe that I just seriously typed
that.)
I have found that game development is
all about The Loop.
Here's a rough overview of an XNA
game's architecture, as well as some of the basics of the API.
If you create a new Windows Game
project in GSE, you begin with two classes. The static class
Program, as you might anticipate, is simple and does little more than
instantiate your game class.
In
XNA, your game class with be a custom class that inherits from
Microsoft.Xna.Framework.Game. You create your game by
implementing some methods in your custom game class. Here's what
they are and what they mean:
Initialize – this is called once,
when your game first starts. As the name implies, you initialize
everything here. Everything except the items related to graphics,
that is. You handle that in the another method.
LoadGraphicsContent – this is where all of your graphics related assets are
initialized. Why is there a seperate method for this? It is because
DirectX works very closely with the hardware. You are accessing the
video card directly, but not exclusively. Other
applications might access the video card as well. This means that
you cannot gaurantee the state of the video card. Another
application might overwrite what you have written to the display.
Whenever this happens, and control is return to your game, the
graphics need to be initialized again. This is called a device
reset. In other words, the graphics may need to be initialized more
than once at runtime, and the game calls this method whenever the
device is reset.
There
is a corresponding method for unloading the assets, UnloadGraphicsContent,
but all the tutorials I've seen thus far just use the base
implementation (or the one provided in the template).
The
next two methods, are called in the game's master loop. That means
that they are called over and over, as fast as the machine can call
them.
Update – this method updates the state of the game. It is where all of
the game logic takes place. Here you check for player input, perform
AI or physics calculations, and whatever else your game “does”.
Draw – this method renders your game. It normally begins by clearing
the graphics device, and then you paint all your pretty graphics to
the screen.
Both
of these methods receive an instance of GameTime. This is part of
the XNA framework, and it provides you will lots of useful
information about how much time (or how little) has passed since the
last iteration of the loop. This is how you are able to make things
in the game (animations, or AI behaviors) take a certain amount of
time without basing it on the processing power of the computer (like
many older games). That is, on how fast the loop is executing.
I
learned most of this from the video tutorials on http://www.xnatutorial.com/.
I will comment though that these tutorials are painfully tedious if
you already know C# and Visual Studio. The author assumes that you
know nothing (which is nice, of course, if you really know nothing).
Components
XNA has another spiffy feature called components. There are a
couple of interfaces, as well as base implementations of these
interfaces, that allow you to build reusable game components and
share them across projects. Components can be all kinds of things.
For example, you could create a component that simplifies processing
user input from the mouse and keyboard. Or you might have a
component that represent a single unit in a RTS game and is
responsible for processing its own AI as well as rendering itself.
XNA provides two base
implementations:
The first is for purely
logical components, like the mouse and keyboard input example. The
other is for components that need to be rendered.
GameComponent has the Initialize and Update methods just like the Game class,
and DrawableGameComponent adds the LoadGraphicsContent and Draw methods.
The Game class also has
a member property of type GameComponentCollection, called Components. You add all of your components to this collection,
and once there the component's methods are automatically called by
the instance of the game. Game.Update() calls
GameComponent.Update().
There is also a nice Dependency
Injection (or Inversion of Control) facility built into the
framework. The container is a collection on the Game class called
Services.
What Threw Me Off
There are no such
things as controls in XNA. There is no Button class that
raises a nice Click event. We are flying closer to the surface with
XNA.
In your implementation
of the Update method, you have to check the state of the
mouse/keyboard/controller and take the appropriate actions.
For example, you might
check to see if the left mouse button is pressed, if it is then you
will need to determine what it is currently over. (Where did I paint
the button on the screen?) I found some useful tutorials about this
here http://www.xnaresources.com/pages.asp?pageid=8.
Just to drive this
point home, if you want to know when the user clicks on a menu
button, then in every iteration of the loop, you check to see if the
mouse button is pressed. Then you compare the X,Y coordinates of the
mouse to the bounding box of the button. If the mouse position is
contain within the box, then you know the gamer clicked your button.
Secondly, all of your
logic is executed in a loop. If you do something like this in your
Update method:
if (Mouse.GetState().LeftButton == ButtonState.Pressed) boolValue =
!boolValue;
Then the bool might
toggle a dozen time during the single click. It's a different way of
thinking.
I
am collaborating with some friends to produce an entry for the
upcoming Dream
Build Play contest sponsored by Microsoft. Hopefully, we'll do
better than we did in the Code Master Challenge. :-)
In the meantime, here are some additional links regarding XNA:
Posted
01-02-2007 10:54 PM
by
Christopher Bennage