Create a new project
To get started, create a new C# windows application in Visual Studio .NET (VS.NET). Right click the project in the solution explorer and add references to the Microsoft.DirectX and Microsoft.DirectX.DirectDraw components. Now, in the source code for the form that is generated, add the following lines:
using Microsoft.DirectX using
Microsoft.DirectX.DirectDraw
Make sure your project references the DirectX and DirectDraw libraries.
The first thing we need to establish for the game is a DirectDraw device. The DirectDraw device is the object onto which we can project a DirectDraw surface, which is the 2D space that the game graphics will occupy. The way DirectDraw renders graphics is to use two separate surfaces or buffers that are alternated between - a primary surface and a secondary surface. Using this technique, it is possible to draw our graphics onto the secondary surface before it is rendered to the device, and this prevents any flicker or redraw from interfering with the display. We will also need to create a clipping object to handle the device limits so that the application isn’t trying to render onto surfaces that lay outside the perimeter of the device. These variables should be added to the form class and made public as shown here.
public Device ddDevice = null;
public Surface ddSurface1;
public Surface ddSurface2;
public Clipper ddClip = null;
Write the core functions
The first thing we need in our game is an initialisation routine that creates the DirectDraw device. The device requires a description objevt that contains configuration data about the device. For instance, our device description is set to use primary surfaces (PrimarySurface = true) with flipping enabled (Flip = true). In order for flipping to work, however, the device must be defined as complex (Complex = 1) which means that it incorporates multiple surfaces. We also create a clipping object, bind it to the current window, and then assign it to the primary surface (ddSurface1).
public void Initialise( )
{
ddSurface1 = null;
ddSurface2 = null;
SurfaceDescription ddSDesc = new SurfaceDescription();
Clipper ddClip = new Clipper(ddDevice);
ddClip.Window = this;
ddSDesc.SurfaceCaps.PrimarySurface = true;
ddSDesc.SurfaceCaps.Flip = true;
ddSDesc.SurfaceCaps.Complex = true;
ddSDesc.BackBufferCount = 1;
ddSurface1 = new Surface(ddSDesc, ddDevice);
ddSurface1.Clipper = ddClip;
ddSDesc.Clear();
ddSDesc.SurfaceCaps.BackBuffer = true;
ddSurface2 = ddSurface1.GetAttachedSurface(ddSDesc.SurfaceCaps);
}
Next up, we will need a game loop function. This function will execute so long as the game form exists and will handle things like redrawing the surface is focus is lost and restored. Our game loop starts off looking like this.
private void GameLoop()
{
do
{
if(this.Focused)
{
RenderSurface();
}
Application.DoEvents();
}while(this.Created);
GameOver();
}
As you will see, the game loop function calls the RenderSurface() function on each iteration where the window is focused. For now, we will create a simple function that draws a colour to the back buffer (ddSurface2) and then flips the primary and secondary surfaces.
public void RenderSurface()
{
ddSurface1.ColorFill(Color.Black);
ddSurface1.Flip(ddSurface2, FlipFlags.Wait);
}
The game loop also calls a function called GameOver() if it detects that the form has been closed. This routine is required to dispose of our DirectDraw objects as shown below.
public void GameOver()
{
ddDevice.Dispose();
ddSurface1.Dispose();
ddSurface2.Dispose();
}