Breakout 3D

For educational purpose only

Ok, I'm sorry for not havingthe imagination to come up with something on my own but I really lovethose classic games. I really miss those days when everything wassimple and in two directions. But now it's different, people today musthave everything in 3d. So here it is, my version of breakout.

The game resolution is 1024×768 and theobjects are many and rather complex, therefore the game needs quitegood hardware to run properly. I designed the game to run 50 f/s.

Known bugs :
At some hardware/driver configurations bricks are not present.

General Information :
To play this game you will need to install .NET framework and managed DirectX 9.0(mdxredist.msi).

To compile this game you will need to install.NET framework and DirectX 9.0 SDK(dx9sdk.exe). If it won't compileinclude the resource files (.dll) that is needed from the fileDirectX.cab and put them in the folder Microsoft.NET/framework/vxxxx/in under Windows.

The resources :
The sound effects are freeware from http://www.flashkit.com/soundfx/
The songs are for you to copy to folder Audio/Mp3/
The Textures are from http://www.redfieldplugins.com/Textures.htm
The DirectX objects are made with Maya 4.0
The backgrounds are freeware from http://www.mediabuilder.com/

Description

The first thing I do when I'm programmingsomething that I haven't worked with before is of course to gatherinformation. I found the main things I needed for my project in thesamples given in the SDK. Microsoft didn't make this any easy readingthough.

I think that it's really important to fullyunderstand every piece of code you write. The people that doesn't agreewith me and just copy code from other projects will do later on, whenthey try to add/change/remove something and they don't know squat abouthow things works.

I would be proud to say that I now knoweverything about the sample code that I read from Microsoft SDK, butguess what, I don't. It seems that if that was my goal I would probablystill be reading it. Because of this there is unfortunately some codethat I do not fully understand, but I managed to get the crucial partsout of it and made some classes to help me in my programming. Classesthat make programming easier is a good thing to do when you learningsomething new.

The classes that are named DirectX are notfrom Microsoft. They are the classes that help me with the structureand the many different DirectX functions. The best things about theseclasses are that they are made for one purpose and of course that theyare recyclable.

As you can see from the diagram all the actionleads to the main class Breakout3d. This class got a little to big anddifficult to understand. Sorry for that but it's quite a big game.

Game Classes

I will not include or comment any code fromthe actual game (game classes) here. It's for you to read by your self.But don't let that stop you. For those who consider themselves to beintermediate programmers the reading should be easy as pie :) .

The main class goes like this :
Timer -> FrameMove -> RenderScene

This is a common structure. The objects andcamera are moved in the function FrameMove() and are rendered inRenderScene(). Together with different states makes this a standard wayto program. This type of programming is also used i.e. real-timeprogramming of state machines.

The code written in this class together withthe different classes for the game objects is the core. It tells useverything about the game, but it doesn't tell us anything about howthe game really is communicating with its surrounding environment. TheDirectXClasses below gives us the necessary information.

DirectXBackground

vertexBackground = new VertexBuffer( typeof(CustomVertex.TransformedColoredTextured ), 4, device, Usage.WriteOnly,CustomVertex.TransformedColoredTextured.Format, Pool.Default );

CustomVertex.TransformedColoredTextured[] v = new
CustomVertex.TransformedColoredTextured[ 4 ];

for(int i = 0; i < 4; i++)
{
v[ i ].SetPosition(new Vector4( position.X, position.Y, position.Z, 1.0f ));
v[ i ].Color = unchecked( ( int )0xffffffff );
}
v[0].Y = ( float )device.PresentationParameters.BackBufferHeight;
v[2].Y = ( float )device.PresentationParameters.BackBufferHeight;
v[2].X = ( float )device.PresentationParameters.BackBufferWidth;
v[3].X = ( float )device.PresentationParameters.BackBufferWidth;
v[0].Tu = 0.0f; v[0].Tv = 1.0f;
v[1].Tu = 0.0f; v[1].Tv = 0.0f;
v[2].Tu = 1.0f; v[2].Tv = 1.0f;
v[3].Tu = 1.0f; v[3].Tv = 0.0f;
vertexBackground.SetData(v, 0, 0 );

To make a background we need to establish fourvertex points in the 3d world, these four vertexes forms a square wherethe background will be drawn.
The first thing we do here is to pick a reference. This is done in thefor loop above where the vertexes are getting same positions. Then justmove them where you want you're background to be placed. Last we call afunction to set the data in the vertex buffer that is linked thedirectx3d device.

Remember that these functions do not exclusively need to be applied on backgrounds.

device.SetTexture( 0, textureBackground );
device.VertexFormat = CustomVertex.TransformedColoredTextured.Format;
device.SetStreamSource( 0, vertexBackground, 0 );
device.DrawPrimitives( PrimitiveType.TriangleStrip, 0, 2 );

This is the code to render the background.First we tell the directx3d device that we want to draw a texture. Thenwe tell the device which vertex format that it should use. Before wecall the draw function we bind the vertex buffer to a data stream port(see the SDK documentation for more information).

DirectXCamera

Matrix view = Matrix.LookAtLH( cameraPosition, cameraDirection, cameraUpDirection );
device.SetTransform( TransformType.View, view );
Matrix projection = Matrix.PerspectiveFovLH( fFieldOfView, fAspectRatio, fNearPlane, fFarPlane );
device.SetTransform( TransformType.Projection, projection );

Every collection of information in a 3d worldis described in matrices. A matrix is a bunch of numbers that describessomething like shapes, functions or in this case information about aslice in a 3d world.

This code tells the device where we want toplace our point of view. First make a matrix over the area you want tolook at with the function LookAtLH () which builds a Left-Handed viewmatrix. Then tell the device that this is our view. The device nowneeds one last thing and that's a perspective. We inform the deviceabout the perspective in the same way as for the view. The functionPerspectiveForLH() builds a left handed projection matrix with thegiven p

arameter
s. If you are programming in 2d you should use thefunction OrthoLH() instead.

DirectXMisc

Contains functions for finding files, show statistic etc.

DirectXFont

Mesh threeDText = Mesh.TextFromFont( device, textFont, text, fDeviation, fExtrusion);

The 3d font is just an ordinary mesh. Thestatic function TextFromFont() builds the mesh. The render and movefunctions are the same as in the class DirectXObject.

DirectXLight

It's not much fun without lights

device.Lights[ lightNo ].Type = LightType.Point;
device.Lights[ lightNo ].Position= lightPosition;
device.Lights[ lightNo ].Attenuation1= fAttenuation;
device.Lights[ lightNo ].Diffuse= diffuseColor;
device.Lights[ lightNo ].Ambient= ambientColor;
device.Lights[ lightNo ].Range= 100.0f;
device.Lights[ lightNo ].Enabled= true;
device.Lights[ lightNo ].Commit();

This is very simple. The device keeps track ofevery light and every light needs to have a unique number. The numberis of type "short" which is a 16 bit variable but you can only useeight active lights at the same time (if you really need to I thinkthere is a way to get more). Then it's just to fill in the propertiesof the light and call the function Commit(). There are three types oflights, directional, point and spot. The code above is for a pointlight. The other lights are created in the same fashion with thedifference that the directional lights don't use the position attributeand the spotlight needs a direction etc. etc.

DirectXObject

This class contains the code for building a mesh from a directx mesh file (.x).

Mesh systemMemoryMesh = Mesh.FromFile(strPath, MeshFlags.SystemMemory, device, out adjacencyBuffer, out Mat); // GraphicsStream ,ExtendedMaterial

Load the .x file. The Extended material "Mat"gets the information about texture names and material properties which(if they exist) can be found in the file. "AdjacencyBuffer" is a streamcontaining graphic data. This variable can be used for optimizing themesh which is a very good thing to do.

systemMemoryMesh.OptimizeInPlace(MeshFlags.OptimizeCompact | MeshFlags.OptimizeAttrSort |MeshFlags.OptimizeVertexCache, adjacencyBuffer );

Optimize, Optimize, Optimize

for( int i = 0; i < Mat.Length; i++ )
{
materials[ i ] = Mat[ i ].Material3D;
materials[ i ].Ambient = materials[ i ].Diffuse;

if ( Mat[ i ].TextureFilename != null )
{
// Create the texture
string texturefilename = DirectXMisc.FindFile( null, Mat[ i ].TextureFilename );
textures[ i ] = TextureLoader.FromFile( device, texturefilename );
}
}

A mesh can have many different textures. Thisfor loop takes every texture that was found in the .x file and createsthe textures.

for( int i=0; i < materials.Length; i++)
{
device.Material = materials[ i ];
device.SetTexture( 0, textures[ i ] );
systemMemoryMesh.DrawSubset( i );
}

To render the object just tell the device whatmaterial and what texture to use and then call the functionDrawSubset() from the mesh object.

DirectXSound

AudioVideoPlayback.Audio mp3 = new AudioVideoPlayback.Audio("mySong.mp3");
mp3.Play();

As you can see above, to play an mp3 in adirectx application is a very easy thing to do, thanks to theAudioVideoPlayback classes and functions.

DirectSound.Device soundDevice = new DirectSound.Device();
// game = the main form = System.Windows.Forms.Control
m_soundDevice.SetCooperativeLevel( game, DirectSound.CooperativeLevel.Priority );
DirectSound.Buffer sounds = new DirectSound.SecondaryBuffer( "myWav.wav", soundDevice );

To play sounds is a little more work. First we must create a device for the sound and then set the CooperativeLevel.

sounds.Play( 0, DirectSound.BufferPlayFlags.Default );

Then just press play

Breakout3dMap

The program I wrote to create maps. I wrote it in two hours so don't expect much.

What you can learn or copy ;)

Mp3 implementation
Sound implementation
Meshes, textures and objects (Backgrounds, 3d Fonts ..)

I'm not an expert or professional programmer.I just program on my spare time so this article could contain errorsand misleading information. If it does then I'm sorry and you can writeto my e-mail and yell at me :) . But I hope it does more good than harm.Good luck everyone!

About the Author:

Mathias Edman
JustAnotherProgrammer@hawaii.com

Download Source Code

Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!