Blue Theme Orange Theme Green Theme Red Theme
 
Home | Forums | Videos | Photos | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
ANTS Performance Profiler 6.0
 Resources  
Close
 Our Network  
Close
Search :       Advanced Search »
Home » DirectX » Space Breakout - 2D Game Developed using DirectX and C#

Space Breakout - 2D Game Developed using DirectX and C#


GDI+ is a feature rich graphics API that makes sophisticated graphical effects highly accessible to the C# developers.

Total page views :  30973
Total downloads :  1047
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
SpaceBreakoutCode.zip
 
Become a Sponsor

Article Description

GDI+ is a feature rich graphics API that makes sophisticated graphical effects highly accessible to the C# developers. Unfortunately if youve tried to develop smooth detailed animation using GDI+ you have undoubtedly discovered that just how slow it can be. Consequently it is not particularly suited to games development, if you want to really take advantage of your 1 gig + processor and that fancy new graphics card youre going to have to get a little more low level and dirty, enter Microsofts DirectX API.

DirectX is a collection of COM dlls developed by Microsoft with games programming particularly in mind. DirectX communicates more directly with the computer hardware (ie Video Card, Sound Card etc..) then GDI+ yet still maintains a sufficient level of abstraction, freeing the developer from the particulars of the hardware running on the users machine.

Unfortunately .net and C# is not an officially supported platform for DirectX development and will not be until DirectX 9 is released at the end of the year. However we can use DirectX with C# in the meantime by using the Visual Basic type library's that come with version 7 and 8 of the API. This article uses the example of a relatively simple Breakout style game imaginatively called Space Breakout to demonstrate how to use the DirectX VB Type Lib in C#.

The Game

Figure I

Figure I is a UML diagram of the games design. There are eight classes in total, one class that represents the main windows form, one class which encapsulates the main directx objects, five classes which deal with the game sprites and a class that represents the group of block sprites. Each of these classes will be dealt with in detail below. To play the game use the left and right arrow keys to move the paddle and space to launch the game ball, to exit the game press the escape key.

DirectX and Direct Draw

DirectDraw was the main 2D interface to DirectX prior to version 8 (which is the latest version of DirectX). Since 2D graphics are no longer the mainstay of windows game programming Microsoft decided to merge the 2D and 3D elements of the DirectX API into a new interface known as DirectGraphics. There are advantages to this approach, however if you want to develop purely 2D games without any hardware accelerated 3D there are several disadvantages, the biggest being:-

Direct Graphics requires a 3D accelerator card for hardware 2D acceleration
Generating 2D graphics in DirectGraphics is more complex then using DirectDraw as it requires knowledge of 3D concepts.
Therefore when developing purely 2D games DirectDraw is probably the first place to start as it is still possible to create a DirectX7 object(which supports directDraw) under DirectX8.

Setting up a DirectX Application

Before we can begin a .net DirectX application we need to create a reference to the DirectX COM dll. In Visual Studio.net this is done by choosing Add Reference from the project menu. If DirectX 7 or 8 are installed on your machine then you should see a reference to the DirectX for Visual Basic Type Library under the COM tab of the Add reference Dialog. DirectX applications in .net must be based on a WinForm, so the next step is to create a standard borderless WinForm.

Initialising DirectX

In SpaceBreakout the main DirectX objects and their initialisation are encapsulated in the GameDirectDrawClass. There are two main display modes in DirectDraw, full-screen mode and windowed mode. Full-screen mode is the most useful for game development as DirectDraw is able to monopolise the users graphics display while the game is running, this in turn leads to significantly better performance in comparison to windowed mode. The following variables are used in the GameDirectDrawClass to initialise Full-Screen mode (through out the article I will be assuming that you have the statement 'using DxVBLib;' at the top of your code file):-

private DirectX7 m_objDirectX = new DirectX7();
private DirectDraw7 m_objDirectDraw;
private DirectDrawSurface7 m_objPrimarySurface;
private DirectDrawSurface7 m_objBackBufferSurface;
private DDSURFACEDESC2 m_objPrimarySurfaceDescription;
private DDSURFACEDESC2 m_objBackBufferSurfaceDescription;

m_objDirectX is the main DirectX instance that is used by the game and predictably m_objDirectDraw is the main DirectDraw instance for the game. The next two variables (m_objPrimarySurface and m_objBackBufferSurface) are DirectDraw surfaces, a surface represents the actual drawing surfaces that we use and are analogous to 'Graphics' objects in GDI+.

Every DirectDraw application must have at least one surface which represents the actual video buffer being rasterised and displayed by the graphics card, this is usually refered to as the primary surface and will be created using the m_objPrimarySurface variable. In addition to the primary surface an application will have a number of off screen surfaces that exist in memory, the second surface variable which was created is a special kind of offscreen surface known as the Back Buffer (m_objBackBufferSurface).

The Backbuffer surface is used in a process known as double buffering. Double buffering is the process of using a second surface to perform all the drawing which builds up a frame of animation, when all the drawing operations are complete the entire secondary or BackBuffer surface is copied to the Primary surface. The process of copying the Backbuffer to the Primary surface in DirectDraw full screen mode is page flipping. When the pages are flipped the Primary Surface points to the area of memory containing the BackBufferSurface and the Backbuffer points to the area of memory that the Primary surface pointed. The effect is that the Primary Surface object contains the contents of the Backbuffer and the BackBuffer object contains the contents of the primary surface. Once the pages have been flipped the BackBuffer can be cleared and the next frame drawn, figure II demonstrates the process.

Figure II

The remaining two variables m_objPrimarySurfaceDescription and m_objBackBufferSurfaceDescription are used to set the properties of the two surfaces and will be explained later on.

The method in the GameDirectDraw class that initialises the direct draw objects is InitialiseDirectXFullScreen(), it has one argument which is an integer representing the handle of the game's form. The code for this function is below:-

InitialiseDirectXFullScreen(int objDisplayFormHandle)
{
m_objDirectDraw = m_objDirectX.DirectDrawCreate("");
m_objDirectDraw.SetCooperativeLevel (objDisplayFormHandle,
ONST_DDSCLFLAGS.DDSCL_FULLSCREEN |
ONST_DDSCLFLAGS.DDSCL_EXCLUSIVE);
m_objDirectDraw.SetDisplayMode(640, 480, 16, 0,
ONST_DDSDMFLAGS.DDSDM_DEFAULT);
m_objPrimarySurfaceDescription.lFlags =
ONST_DDSURFACEDESCFLAGS.DDSD_CAPS |
ONST_DDSURFACEDESCFLAGS.DDSD_BACKBUFFERCOUNT;
m_objPrimarySurfaceDescription.ddsCaps.lCaps =
ONST_DDSURFACECAPSFLAGS.DDSCAPS_PRIMARYSURFACE
CONST_DDSURFACECAPSFLAGS.DDSCAPS_FLIP |
ONST_DDSURFACECAPSFLAGS.DDSCAPS_COMPLEX;
m_objPrimarySurfaceDescription.lBackBufferCount = 1;
m_objPrimarySurface = m_objDirectDraw.CreateSurface(
ref
_objPrimarySurfaceDescription);
DDSCAPS2 ddscaps =
new DDSCAPS2();
ddscaps.lCaps = CONST_DDSURFACECAPSFLAGS.DDSCAPS_BACKBUFFER;
m_objBackBufferSurfaceDescription = m_objPrimarySurface.GetAttachedSurface(
ref
dscaps);
m_objBackBufferSurfaceDescription(
ref m_objBackBufferSurfaceDescription);
}

The first line of code creates the DirectDraw object from the DirectX 7 object. Once this has been done the SetCooperativeLevel() method of the DirectDraw object is called, this sets the level of co-operation that the DirectDraw object will have with the operating system. The first parameter is the handle of the form that will be used for the application and the second contain the flags indicating the required co-operative level, the two flags used indicate that we will be using full screen mode and taking exclusive control of the display.

The next DirectDraw method (SetDisplayMode) sets the display mode for the game, the first two parameters indicate that the resolution will be 640 pixels by 480 pixels, the third specifies 16bit colour, the fourth is the refresh rate - by setting it to 0 DirectDraw will automatically use the best rate, the fifth argument indicates that no advanced resolutions are to be used.

Next properties are assigned to the Primary Surface descriptor variable, this variable will be used to create the Primary Surface. First we indicate that the description will specify the capabilities of the surface and it's Backbuffer count, this is done using the lflags property. The next line specifies the sets the capabilities of the surface, the first constant indicates that this will be a primary surface, the next constant indicates that we will be using page flipping to copy the backbuffer to the primary surface and the final constant is needed if we are using page flipping. The next line sets the back buffer count for the surface, it indicates that 1 backbuffer will be used. With the surface description configured the next line creates the primary surface using the CreateSurface() method of the DirectDraw object, the method takes a reference to the surface descriptor as it's one parameter.

With the Primary surface initialised the Backbuffer can then be created. We first need to set the caps property of the Backbuffer descriptor to indicate that this is a BackBuffer surface, we then use the GetAttachedSurface() method of the PrimarySurface object to create the Backbuffer.

Displaying Bitmaps

Bitmaps in DirectDraw must be loaded into new Surfaces and then copied onto the BackBuffer. Since there are a number of bitmap graphics in the game an abstract class (called BitmapObject) contains the code for bitmaps, this class is then inherited by each of the individual game object classes. The main variables used in the BitmapObject class to create a bitmap object and display it on the Backbuffer are:-

public const int BLACK_TRANSPARANT_SPRITE = 1;
public const int NORMAL_BITMAP = 0;
protected DDSURFACEDESC2 m_objDDSurfaceDescription;
private DirectDrawSurface7 m_objBitmapSurface;
protected RECT m_objSizeRECT;

The first two constants are used to indicate whether the object will be a sprite or a standard bitmap(a sprite is a non-square bitmap). Next m_objDDSurfaceDescription is a surface description object and is used to set the properties of the Surface object, m_objBitmapSurface is the DirectDraw surface object that will contain the bitmap. The remaining variable is a RECT which is an object containing rectangular information, it represents the rectangular dimensions of the surface and is used when the surface is copied to the backbuffer.

The surface description is configured in the function InitialiseSurfaceDescription() which is listed below, it contain two arguments which indicate the width and the height of the bitmap:-

InitialiseSurfaceDescription(int intBitmapWidth, int intBitmapHeight)
{
m_objDDSurfaceDescription.lFlags = CONST_DDSURFACEDESCFLAGS.DDSD_CAPS |
CONST_DDSURFACEDESCFLAGS.DDSD_WIDTH |
ONST_DDSURFACEDESCFLAGS.DDSD_HEIGHT;
m_objDDSurfaceDescription.ddsCaps.lCaps =
ONST_DDSURFACECAPSFLAGS.DDSCAPS_OFFSCREENPLAIN;
m_objDDSurfaceDescription.lWidth = intBitmapWidth;
m_objDDSurfaceDescription.lHeight = intBitmapHeight;
m_objSizeRECT.Bottom = intBitmapHeight;
m_objSizeRECT.Right = intBitmapWidth;
}

The first line of code sets the lFlags property of the surface descriptor, it indicates that the description will set the capabilities, the width and the height of the surface. The next line sets the capabilities of the surface specifying that it is an off screen surface. An off screen surface is a surface that exists in memory and is not itself physically visible to the user. The next two lines set the width and height of the surface and the final two lines set the width and the height of the RECT.

Once the surface description is setup the surface can be created, the code for this is in the InitialiseSurface() method. The method takes three arguments, the DirectDraw object for the application, a string indicating the source of the bitmap file and an integer indicating if a normal bitmap or a sprite is to be created. The code for the method is below:-

InitialiseSurface(DirectDraw7 DirectDraw, string strBackgroundBitmap, int intBitmapType)
{
try
{
m_objBitmapSurface = DirectDraw.CreateSurfaceFromFile( strBackgroundBitmap,
ref m_objDDSurfaceDescription );
}
catch ( Exception e)
{
System.Windows.Forms.MessageBox.Show( "Unexpected exception: " + e.ToString(), "Unexpected Exception" );
System.Windows.Forms.Application.Exit();
}
switch (intBitmapType)
{
case BitmapObject.BLACK_TRANSPARANT_SPRITE:
DDCOLORKEY objBlackKey;
objBlackKey.low = 0; objBlackKey.high = 0;
_objBitmapS
urface.SetColorKey( CONST_DDCKEYFLAGS.DDCKEY_SRCBLT,
ref
bjBlackKey);
break;
}

The first section of code attempts to create a DirectDraw surface object using the specified bitmap file. This is done using the CreateSurfaceFromFile() method of the applications DirectDraw object. CreateSurfaceFromFile() takes two parameters, a string indicating the source of the bitmap and the DirectDraw surface description object which was configured earlier.

The final section of code is used if a sprite is being created. As I mentioned earlier a sprite is a non-square graphic, unfortunately bitmap files can only be square therefore DirectDraw has to turn a square graphic into a sprite. This is done by defining a color key for the surface, DirectDraw will then make any part of the bitmap that is the specified colour transparent when it overlaid on another surface. All the sprites in the game use black for the colour key, the first line of code creates a DirectDraw colour key object and the next two lines set it's high and low colours to black. Next the SetColourKey() method of the bitmap surface object is called, the first parameter specifies that the colour key is to be applied to the bitmap surface object and not the surface that the object is being overlaid onto, the second parameter is a reference to the colour key object that was just created.

With the bitmap surface created it can be overlaid onto the Backbuffer surface, the process of overlaying one surface onto another is known as 'blitting' which is colloquial for "bit block transfer". To blit a bitmap surface onto the Backbuffer the BltFast() method is used, the following code is used in the BltFast() method of the games BitmapObject class to blit a sprite onto the backbuffer using the colour key for transparency:-

objBackBufferSurface.BltFast( this.XPosition, this.YPosition, m_objBitmapSurface, ref m_objSizeRECT, CONST_DDBLTFASTFLAGS.DDBLTFAST_SRCCOLORKEY | CONST_DDBLTFASTFLAGS.DDBLTFAST_WAIT );

The first parameter of the BltFast() method is the number of pixels from the left of the Backbuffer that the sprite will be placed; the next parameter is the number of pixels from the top to position the sprite; the third is the surface object of the sprite; the fourth is a RECT which indicates the size of the area being blitted to and the final parameter is the blitt flags to use; the two used indicate that we are using a colour key for the object and that DirectDraw is to wait until blitting is completed before moving to the next operation.

Flipping the Backbuffer to the primary surface

Once all the bitmaps for a frame have been blitted to the backbuffer it needs to be flipped to the Primary surface. This is done in the FlipBackBufferAndPrimary() method of the GameDirectDraw class. The method has one line of code which is:- this.PrimarySurface.Flip(this.BackBufferSurface, CONST_DDFLIPFLAGS.DDFLIP_WAIT); As you can see the Flip() method of the Primary Surface object is called, the method has two parameters. The first parameter is the Backbuffer surface object and the second is a flag indicating that DirectDraw should wait until the flipping is complete before moving onto the next operation. Once the flipping is complete the backbuffer can then be cleared and the next frame of animation blitted to it.

Conclusion

This article has detailed the core elements of building a game using DirectX and DirectDraw. DirectX is a huge topic but it is hoped that in conjunction with the source code for the Space Breakout game you'll have all you need to begin building your own 2D DirectX games.


Login to add your contents and source code to this article
 About the author
 
Mark Johnson
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
SQL and .NET performance profiling in one place
Investigate SQL and .NET code side-by-side with ANTS Performance Profiler 6, so you can see which is causing the problem without switching tools.
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today.  With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications.  Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
60 FREE UI Controls from DevExpress
Register for your FREE copy on over 60 free presentation controls from DevExpress - Absolutely Free-of-Charge without any royalties or distribution costs. Visit Devexpress.com/60 today. Free controls include advanced lists box, dropdown calendar, rich text edit, spin edit, tab control and so much more!

DevExpress engineers feature rich presentation controls and reporting tools for WinForms, ASP.NET, WPF, and Silverlight. Our technologies help you build your best, see complex software with greater clarity and deliver compelling business solutions for Windows and the web in the shortest possible time.
Clickatell's SMS Gateway
Clickatell's Developer Solutions allow you to SMS enable any website or application via a range of API's. Learn More about our API connections.
Free access to .NET Memory Management video
Everything you need to know about Garbage Collection, Temporary Objects, Fragmentation, Finalization and common causes of memory leaks in .NET. Watch the video here.
Microsoft Visual Studio 2010
Visualize your workspace with new multiple monitor support, powerful Web development, new SharePoint support with tons of templates and Web parts, and more accurate targeting of any version of the .NET Framework. Get set to unleash your creativity.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
Developer-Ready ASP.NET 2.0 Web Hosting with 3 MONTHS FREE
Now supporting .NET 3.0 Framework with Windows Workflow Foundation, Windows Communication Foundation (WCF), Windows Presentation Foundation (WPF), windows CardSpace (WCS)! Providing more flexibility for Developers with Web Services Support and a User/Permission Manger. Also supporting MS SQL 2005/2000 with Real-Time Backups, FREE Automated Attach .MDF Tool, FREE SQL Restore and Shrink SQL DB Tools, and SQL
Read the Top 10 Books for Microsoft Developers, 15 Days FREE
Read the Top 10 Books for Microsoft Developers, 15 Days FREE
Try Safari Books Online - 15 Days FREE + 15% Off for 1 Year
Try Safari Books Online - 15 Days FREE + 15% Off for 1 Year
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Nevron Diagram
Become a Sponsor
 Comments
HI Mark by Darko On December 10, 2007
I want to change the way the bricks are positioned. Is this possible simply or i have to rewrite the whole Blocks code ? Pls.help me out here man :)
Reply | Email | Delete | Modify | 
X64 by Tim On June 10, 2009
If you get the message

Unexpected exception: System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM class factory for component with CLSID {E1211353-8E94-11D1-8808-00C04FC2C602} failed due to the following error: 80040154.

you need to set the platform target to x86 - just thought I'd post this in case anyone else had the same problem as me.
Reply | Email | Delete | Modify | 

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2010.8.14
 © 2010  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.