In the late seventies, while in high-school, I had been interested like a lot of geek teenagersÂ in how basic games worked. At the time, I had invested in the only affordable computer I could get my hands on, a Sinclair ZX 81.
It was a cool machine as it not only included BASIC but also exposed PLOT commands to create low resolution graphics. You could also program in Z80 CPU instructions – provided you could compile them by hand (gee! does this date me or what?!). Being in advanced math classes meant that you could program and plot math functions and write your own matrix transformations – say, to rotate a cube in 3D for example. Once I left high school however, I never went back to computer graphics, until now.
In the last year or so I have been keeping an eye on articles related to game development either based on the Microsoft XNA game development platform or on Silverlight. In fact, a recent article on MSDN magazine, “Building Advanced 3D Animations with Silverlight 2.0″ triggered the ZX81 memory of matrix-based rotations! And seeing my 11 year old son play hosted web games written in Flash gave me a renewed interest in the topic. I just needed a catalyst. The DotNetRocks episode 418 , with Dan Fernandez and Brian Peek, acted as that catalyst. I ordered the book, Coding4Fun, and started on the first chapter: Alien Attack – which is your typical Space Invaders game like the ones I played in cafes back in France during high-school!
The book did a reasonably good job at having the developer add functionality in layers but its mission was not to explain the architecture of the game or its relationship to XNA. So I decided to write this blog post to present the internal architecture of the game. First, let’s look at the core concept, and then let’s proceed to the layering and class structure of the game.
- Core loop – two primary steps take place over and over
1. The update process happens recursively from the game, to the active screen, to each of the screen’s components
2. At the game level we can decide whether to stop or pause or save the game based on input
3. At the screen level, we can:
a) move components based on input, trajectory or velocity
b) detect collisions
c) create new objects based on the rules of the game: e.g. create shots or explosions
d) delete objects based on rules: e.g. delete shots once they have left the screen, delete explosions once they are done
e) play sound effects
1. The drawing process happens recursively from the game, to the active screen, to each of the screen’s components
2. The screen asks each of its component to draw itself
3. Each screen component may rely on sprite animation
- Game components
1. A screen represent a phase of the game – e.g. introduction, first level, etc.
2. A screen is made of components such as the scoreboard, mothership, enemies, shots, explositions, etc.
3. A screen component uses a sprite to represent its visual characteristics over time
- Sprite Animation
1. Uses several graphics each representing a frame in the animation
2. Loops through each frame using an index for the current frame
3.Â At drawing time, draw the current frame
- Collision detection
1. In Alien Attack, simple bounding box intersection (i.e. is the laser shot rectangle intersecting with an alien ship rectangle) check is performed
2. We test for collision between:
a) a laser shot fired by the mothership and an alien ship (mothership wins)
b) a laser shot fired by the alien ship and the mothership (alien wins)
c) an alien ship and the mothership (crash)
The game due to its basic structure only relies on a small subset of the XNA framework.
At the core, creating a new game means subclassing the Microsoft.Xna.Framework.Game class and overriding the two core methods:
- void Update(GameTime gameTime)
- void Draw(GameTime gameTime)
Update can take into account the game time and manage the active screen, as well as delegate to the screen the update of its visual components.
Draw allows you to drawn strings or graphics as you would expect.
The minimal class diagram looks like this:
See the note on each class above for its core purpose.
The game is organized around two screens, the title screen serving as the introduction, and the main game screen. The overall AlienAttackGame class manages which of the two screens should be active by asking the current screen to return what should be the next screen once its update is complete. So for example when the TitleScreen detects that the Enter key has been pressed, it will return the GameScreen as the next screen to display. The game will then instantiate the Game screen and make it the active screen.
The GameScreen implementation consists of implementing its visual components in the following sequence:
- the mothership (known as the “player” in the book – I renamed to make it sound more fun.
- the laser shots appearing when the gamer hits the space key
- the enemies and their random laser shots
- the explosions triggered when collision occurs
- the scoreboard
I used a combination of the prefabricated graphics and sounds available on the Coding4Fun web site. But I also made my own custom graphics and titles using Adobe Photoshop Elements (but you can also use Microsoft Expression Designer, Paint.NET or your favorite graphical designer).
To make it easier for the visual components to be animated, a “sprite” model is used. This is a class which will keep track of the individual graphics (frames) making up the animation. For example the laser shots animation toggles between two images, while the explosion uses 10 images:
So for each visual component, a subclass of Sprite is created. The most complex component is the EnemyGroup which manages the matrix of enemies and make it move back and forth across the screen, while firing laser shots randomly!
The full class diagram once the game is complete looks like this:
It takes a few hours to implement the game using the book and if you follow an even more incremental approach than what the book recommends, you can see the game evolve pretty well and have quite a bit of fun along the way!
Once you get the architecture of the game you can proceed with more refinements, for example:
- Play with textures on individual frames and objects
- Customize the graphics and sounds
- Implement multiple enemy groups to make the game harder
- Implement more complex collision detection
- Vary speed and complexity based on levels
A few things to note as well:
- XNA supports the Zune (I did not try that out since I have an iPod) and of course the XBox
- Silverlight currently does not support XNA directly although SilverSprite, an open source project provide some amount of cross-platform support
- Games can be written in most CLR-based languages. One of the next things I will play with is to use IronRuby to write the game.
I hope that this post will encourage more people to try XNA for game development!