3D game Programming

Coming Up with the Game Idea

Everything that has ever been created started out as an idea, and games are no different. Game ideas can come from just about any source you can think of. Perhaps you saw another game that you enjoyed, but thought it would be so much better if it did something differently. Maybe you had a dream that would make the perfect game. Perhaps you realized two unrelated games could be combined to create the ultimate game. Wherever your inspiration comes from, you'll need to tap into that before you can start making your game.
Unfortunately, as no one has yet invented a mind-reading book, you'll have to trust my ideas for this game. I chose the games in this book for a variety of reasons, mainly concerning the level of development difficulty. However, each is in a different genre to cover the wide variety of topics you'll encounter in your game development coding.
The first genre is the puzzle game. It's probably safe to assume you have seen or played puzzle games before. Tetris is a classic puzzle game that just about everyone has either heard of or lost tons of hours of sleep playing. Everyone it seems has also written a Tetris clone, so it likely wouldn't be the best choice for the puzzle game you will be writing. Also, Tetris is a 2D sprite game (although there have been 3D Tetris-type games), so you will probably want to skip it for that reason as well.
Instead, you should write something somewhat unique. The game will have a single character that is on a board. This board will be made up of a series of cubes in an undetermined pattern, with each cube having at least one other cube directly adjacent to it. A chess board would be an example of a board that meets these criteria. Each cube will be a particular color, and when the player steps on one of these cubes, it will change to the next predetermined color. The level will end when every cube in the level is on the correct color for that level.

Detailing the Proposal

Like you learned in the previous chapter, once the basic idea for the game is laid out, you should spend some time coming up with the game proposal, ensuring you answer as many questions as possible. For this game, here is a bulleted list of items to help detail the proposal:
  • Puzzle game called Blockers
  • Single-player only
  • Fully 3D environment
  • Score based on time to complete level
  • Each level consists of a series of adjacent cubes, such as found on a chess board
  • Each cube is always a single solid color
  • Each level will end when every cube in the level is the same color, and that color is the predetermined "end" color for that level
  • Each level will have a maximum time limit
  • Each cube will have a "list" of colors assigned to ithis list will have a minimum of two colors, with a maximum of six
  • Players move by "bouncing" on a cube, which will change the color of the cube to the next available in the list
  • Beginning levels will have the minimum list of two colors per cube
  • Difficulty will be raised by adding more colors per cube in more advanced levels
  • If player can finish these levels, difficulty will be raised once more by allowing the color list to "wrap" back to the beginning
  • Game is over if player cannot complete level within maximum time limit
Is this an exhaustive list of every feature of the game? Probably not, but it does answer the majority of questions that you need to answer before you can start planning the game. It's important to understand that the planning phase isn't designed to detail every feature of the game before you begin development, but more to get you thinking about the features your game will require. Jumping in and coding without considering the features you really want will lead to more difficult work later in trying to fix the things you missed or did incorrectly because of a rushed plan.

Much of the game requires information about the current level. The current time is important because it will be used to determine both the high scores and when the game is over (when it runs out), so the current level must have access to it.
The actual levels themselves will be stored in the file system, in the media folder of the application. Because the current level will need to load one of the existing levels, it will of course need access to those as well. The only thing the level really needs to keep track of is the list of cubes that comprise the level. Each level will have at least two cubes, but can add many more to accommodate larger levels.
This game won't be easy to write, but as you can see, there aren't many objects that you will need to create to ensure that the goals of the game are met. The game has the potential to be quite fun as well, as long as the more difficult levels don't become so difficult that they end up frustrating the player. A game can do nothing worse than annoy the player. If the game isn't fun, no one will play it, and the game cannot be considered successful.

Understanding the Need for a 3D Game

It's important to realize that this game (actually, any game) does not "need" to be rendered as a fully 3D world. Considering that your monitor is most likely a rectangular flat plane, even your fancy 3D rendered images will be displayed on a 2D plane. It would be entirely possible to create a set of 2D sprites that cover every possible scenario that would need to be displayed in your world, but the art assets required for something like this would be enormous. Look at this experiment as an example.
Assuming you have the DirectX SDK Summer 2004 Update installed, load the DirectX Sample Browser and make sure the Managed option is the only item checked on the left. Click the Direct3D heading, scroll down to find the Empty Project item, and click the Install Project link, following the steps of the wizard (naming the project "Teapot"). Once the project has been created, load it into the IDE.

This will create a new "empty" project. (It actually renders some user interface controls, but for now, those can be ignored.) However, there isn't anything 3D in this project yet, and because the point of this exercise is to show why you'd want to write 3D games, it might be a good idea to add some now.
You'll need to add a few lines to this project to make it render a slowly spinning teapot. You'll be adding a few lines of code to make this application do the rendering, although for this chapter the explanations of what exactly is going on will be skipped. There will be plenty of time throughout the rest of the book for these explanations, but they are not necessary for this demonstration. Assuming you named the project "Teapot," open up the code file teapot.cs and add these two variables to the class file:
private Mesh teapotMesh = null; // Mesh for rendering the teapot
private Material teapotMaterial; // Material for rendering the teapot

Now you'll want to create the teapot and material you'll be using to render the scene, so find the OnCreateDevice method in this class and add the following code to the end of the method:
// Create the teapot mesh and material
teapotMesh = Mesh.Teapot(device);
teapotMaterial = new Material();
teapotMaterial.DiffuseColor = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f);

To make the teapot look better, you'll want to have a light (these will be explained in much greater detail later), so for now, find the OnResetDevice method in your class and add this code to the end of it:
// Setup lights
device.Lights[0].DiffuseColor = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f);
device.Lights[0].Direction = new Vector3(0,-1,0);
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Enabled = true;

You're just about ready now. Find the OnFrameRender method in your class and add this code directly following the BeginScene call:
device.Transform.View = camera.ViewMatrix;
device.Transform.Projection = camera.ProjectionMatrix;
device.Transform.World = Matrix.RotationX((float)appTime);
device.Material = teapotMaterial;
Running this application renders a teapot. Teapots have quite a storied history in the world of 3D rendering. One of the first "free" models available for rendering was a teapot, and considering that back then the complex modeling packages that we have today didn't exist, creating an actual 3D model was complicated. Anything free was welcomed. The teapot also has plenty of properties that make it an excellent test model: it has curved surfaces, can shadow itself, and is recognized easily.

As the application runs, watch as the teapot rotates slowly. It's important to realize that the only media required for this application is the teapot model. No media is actually required for this model because you used a method in the Mesh class (which will be discussed in a subsequent chapter) that created the teapot for you. So, you get a nice looking teapot at a minimal media cost.
Now let's compare this to rendering a teapot in the 2D world. Create a new project using the DirectX wizard once more.
If you install the code found on the included CD, you'll notice a media folder that actually contains all the media for every example you will be writing during the course of this book. One of the pieces of media you will notice is the 2dteapot.bmp file, which is an example of what you'd need to render your teapot in a 2D environment. The biggest difference between the 2D and 3D world is the media requirements. The bitmap is currently only showing one view of the teapot, whereas the 3D version can show the teapot from any angle. To show this teapot at any angle in the 2D version, you would need a separate piece of media for each position the teapot can be in. Imagine that you need one image of the teapot for each degree of rotation (360 total images). Now imagine that you want to rotate the teapot around any axis (X, Y, Z). You'll need a whopping 46,656,000 different images of the teapot. Imagine a graphically intensive game such as Unreal Tournament rendered with nothing but 2D sprites. You would need entire DVDs-worth of content, and an army of artists would take years to create something that massive.
If you have an artist capable of creating highly detailed 3D models, you obviously have much more freedom in the scenes you can create with much more "limited" media. A single model can be rendered in so many ways, with various lighting, scaling, positions, rotations, that it is so impractical to create this artwork in 2D, it is essentially impossible to do. This power doesn't come free, though.
The freedom that the 3D applications bring takes quite a bit of processing power, so much so that an entire industry has been formed based on providing it. Although there are quite a few companies in the business, the clear leaders as of this writing are nVidia and ATI. There have been so many innovations in graphics cards recently that they are even evolving quicker and becoming faster than the more generalized CPU.
Modern cards (cards that are DirectX 9-compliant, meaning they have support for at least shader model 2.0) are capable of rendering millions of triangles per second. Don't worry; shaders will be discussed later in this book. If you are wondering where triangles came from, it should be mentioned that they are the basic polygon used to create a 3D model.

So, does this game need to be written in 3D? Of course not, you could write it entirely with sprites and without rendering any 3D content, but what's the fun in that? The majority of "teach yourself"-type game development books always cover rendering 2D content, and very few concentrate on the 3D worlds that make today's games great. Although 2D game development hasn't died yet (and may never completely die), if you are in the market for a development job in the games industry, you must have 3D experience.

The Specification
With much of the busywork out of the way, you can start working on one of the most important sections of the gamethe specification. I cannot stress enough the need for you to spend time thinking about the problems you need to solve before you write a single line of code. Virtually every budding game developer I know has started the first game by jumping in and writing some code. You'll only be making more work for yourself later when you realize your quick working solution doesn't quite work the way you intended.
So for this game, what problems need to be solved? 
A common way to display development specifications is with UML (unified modeling language).

Fancy diagrams aside, what really needs to be done for the game? You will obviously need to have a central area where everything is controlled. In this case, it will be the game engine. If you notice in the UML, the game engine will also maintain the graphics rendering device and code as well (which is implied through the InitializeGraphics method). The major things the game engine needs to know are:
  • The player object
  • The current level
  • Is the game over?
  • If so, has the player won the level?
  • If so, has the player won the game?
The game engine will also need to store other information, such as the rendering device, plus maintain the game's objects, but these will occur in private methods and are not shown in the UML from Figure 2.5. The next object is the player, which is actually quite simple. The only information needed for the player is the position it's currently in, and the capability to render itself in the scene. In our game engine, the player is really more of an abstract concept than a development object. The object here is mainly used to control how the player is shown visually.
Everything else in the game engine comes from the levels object. In reality, this object is quite simple as well, because it just maintains a few other objects, notably the blocks collection. Each block maintains all of the information needed to control itself within the level, including the list of possible colors, and whether the colors will roll over.
With the basic specification out of the way, it's time to start coding. You can rest assured that most likely the specification will change slightly between now and the completion of the game, but this gives you a perfect opportunity to start writing some code.


Popular Posts