Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#
Article

DX Game Utility Class Library

Rate me:
Please Sign up or sign in to vote.
5.00/5 (24 votes)
9 Nov 20034 min read 130.4K   1.7K   52   18
A managed DirectX class library that can be used as a foundation for basic 2D games. Demo included.

Image 1

Latest news

For latest news on this project, please visit http://www.danpeverill.com/. Feel free to e-mail me at dan@danpeverill.com with any questions or comments that you may have.

Introduction

I made this project with a single goal in mind; to create a reusable Managed DirectX class library that can be used as a foundation for basic 2D games. I hope that I have succeeded. As a fellow game hobbyist, I present the GameUtil class library to you, so you too can benefit from its code. You can use it in any way you so desire; start your own 2D game, extend and/or alter the code for your own needs, or just browse the source code for learning purposes.

For your convenience and as a mini-tutorial, I've included a demo project that shows how easy it is to get a basic 2D game engine built, using the GameUtil class library.

Requirements

Aside from .NET 1.0/1.1 (which you should have already), you'll need to have the latest version of Managed DirectX SDK (DirectX 9.0 SDK Update Summer 2003 as of this writing). Yes, even the demo project requires it.

Features

DDGameSurface

This class can be used as your game surface, which can be attached to any .NET control. It's been made flexible to allow both window (whether it be a Form or Control) and pseudo full screen modes. It handles everything for you, including the backbuffer work and restoring lost surfaces.

Creating and displaying a DDGameSurface couldn't be any simpler;

C#
DDGameSurface gameSurface = new DDGameSurface(control);

gameSurface.Clear(Color.White);
gameSurface.DrawText(0, 0, "Hello!", false);
gameSurface.Display();

gameSurface.Dispose();

DDGraphic

The DDGraphic class is derived from the Surface class and provides a much more game friendly functionality, which includes setting frames, frame sizes, and retrieving frame areas to draw. This is perfect for animation. But don't worry, you aren't required to actually set any of these details if your graphic doesn't have any frames.

Here's an extension of the above example, which shows how to create and display a DDGameGraphic;

C#
DDGraphic playerGraphic = new DDGraphic("player.bmp", 
    new SurfaceDescription(), gameSurface);
playerGraphic.SetTransparency(0x00111111);
playerGraphic.FrameSize = new Size(32, 32);

if (gameSurface.CanDraw) {
      gameSurface.Clear(Color.White);
      gameSurface.DrawTransparent(0, 0, playerGraphic, 
          playerGraphic.GetFrameArea(0));
}

gameSurface.Display();

playerGraphic.Dispose();

DDGameGraphics

Normally you wouldn't create a DDGraphic directly, instead you'll probably want this class handle all that dirty work. The DDGameGraphics class acts as a lookup table for your game graphics, which you can change on the fly with some simple XML editing skills. This way, you can load all of your game graphics (or graphics for a particular map) with a simple object instantiation. Another thing that this class provides is flexibility. No longer will you need to hardcore all of those nasty constants to where your graphics are located, instead you can use the DDGameGraphics class which loads them for you, using information provided by an XML document. And yes, there is support for embedded graphics.

Here's a taste, further expanding the code above;

C#
// graphics.xml (note that the only required attributes are key and path)
<GameGraphcs>

      <graphic key="player" path="Namespace.player.bmp" 
            frameWidth="32" frameHeight="32" transColor="00111111" 
                 embedded="true"/>

      <graphic key="enemy" path="Namespace.enemy.bmp" 
            frameWidth="32" frameHeight="32" transColor="00111111" 
                 embedded="true"/>

</GameGraphics>

// Game code...
DDGameGraphics graphics = new DDGameGraphics("graphics.xml", gameSurface);

DDGraphic playerGraphic = graphics["player"];
DDGraphic enemyGraphic = graphics["enemy"];

// Draw graphics.

// No need to dispose our DDGraphics, DDGameGraphics does that for us.
graphics.Dispose();

DIMouse

The DIMouse class may seem a bit odd to work with at first. This is because a DIMouse object will only update its internal state when the Update() method is called. Everything else however, is a breeze to understand and use. The DIMouse class encapsulates pretty much everything you'd expect to get from a mouse, including cursor coordinates, button clicks (even wheel clicks), and wheel movement. Unlike a DDGameSurface however, a DIMouse must be created for a Form.

Here's a quick example;

C#
DIMouse mouse = new DIMouse(form);

// Inside game loop.
mouse.Update();
if (mouse.LeftClick) {
      Console.Writeline("Left click at coordinates: " + mouse.Location);
}
// --

mouse.Dispose();

DIKeyboard

DIKeyboard works identically to the way DIMouse does, except that it has a different interface for accessing keyboard information.

DIKeyboard in action:

C#
DIKeyboard keyboard = new DIKeyboard(form);

// Inside game loop.
if (keyboard[Key.A]) {
      Console.Writeline("The A key is pressed!");
}
// --

keyboard.Dispose();

QPTimer

What game would be complete without some sort of high performance timer? The QPTimer class encapsulates the Query Performance Counter and Frequency for you, so all you have to do is work with its simplistic interface. And don't worry, the ticks per second is a floating point number. As a side note, there isn't a property that returns the ticks per millisecond, but that's easy enough to solve on your own - just multiply the TicksPerSecond property by 1000.

A game loop example showing off the QPTimer :

C#
QPTimer timer = new QPTimer();
timer.Start(QPTimer.Counter);

while (gameRunning) {
      timer.Record();

      // Process mouse input.
      // Process keyboard input.
      // Update game logic with timer.TicksPerSecond.
      // Draw graphics.

      Console.Writeline("FPS: " + 1.0F/timer.TicksPerSecond);

      timer.Start(timer.RecordTime);
}

GameUtil Demo

Just giving you a class library without actually showing how it's used to create a game engine would be quite pointless. So I've gone ahead and created a demo which shows how to put most of the GameUtil class library's features to work. Heck, if you really wanted to, you could use the demo as a template for creating your own 2D game. At the very least, it'd make a good tutorial on how to get started.

I would like to point out a note or two; The FPS shown in the demo are slower then what you'd expect in an actual game, simply because the demo engine is doing some reflection work and also updating .NET controls at the same time (I was more interested in showing features than making it efficient). Despite this, the demo can draw about 2,500+ graphics and still get a steady ~30 FPS (my computer is an 800mhz Athlon, with 250mb of PC133 RAM and a Geforce 2 MX, so your mileage may vary).

Closing Comments

Thanks for reading, and I hope you find this class library useful.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralWonderful!! Pin
invisible8615-Jul-10 7:02
invisible8615-Jul-10 7:02 
GeneralDirectX and VS2005 Pin
Tareq_Gamal13-Aug-06 1:28
Tareq_Gamal13-Aug-06 1:28 
GeneralDirectDraw Transparency problem Pin
Mishan Pog3-May-05 5:53
sussMishan Pog3-May-05 5:53 
GeneralRe: DirectDraw Transparency problem Pin
gbravoo28-Apr-06 0:50
gbravoo28-Apr-06 0:50 
QuestionNew Version ? Pin
Boo!18-Oct-04 11:24
Boo!18-Oct-04 11:24 
GeneralAVI Pin
waelahmed24-Jan-04 8:53
waelahmed24-Jan-04 8:53 
GeneralRe: AVI Pin
Andy Acid26-Feb-04 2:22
sussAndy Acid26-Feb-04 2:22 
GeneralManaged Direct X Pin
stano10-Nov-03 21:51
stano10-Nov-03 21:51 
GeneralRe: Managed Direct X Pin
Dan Peverill10-Nov-03 22:18
Dan Peverill10-Nov-03 22:18 
GeneralVery nice Pin
Broken God10-Nov-03 20:05
Broken God10-Nov-03 20:05 
GeneralRe: Very nice Pin
Dan Peverill10-Nov-03 22:19
Dan Peverill10-Nov-03 22:19 
QuestionNice, but....VC6 version? Pin
Roger Allen10-Nov-03 6:43
Roger Allen10-Nov-03 6:43 
When I saw the article title I thought YES! But then I don't have .NET. Do you perchance have a VC6 version of your class library? I have a game I originally wrote in 68000 assembler (OMG | :OMG: ) which would translate nicely using this.


Roger Allen
Sonork 100.10016

Death come early, death come late,
It takes us all, there is no reason.
For every purpose under heaven,
To each a turn, to each a season.
A time to weep and a time to sigh,
A time to laugh and a time to cry,
A time to be born and a time to die.
Dust to dust and ashes to ashes,
And so I end my song.

AnswerRe: Nice, but....VC6 version? Pin
boyone10-Nov-03 7:20
boyone10-Nov-03 7:20 
GeneralRe: Nice, but....VC6 version? Pin
Dan Peverill10-Nov-03 11:42
Dan Peverill10-Nov-03 11:42 
GeneralRe: Nice, but....VC6 version? Pin
WorldMaker11-Nov-03 9:11
WorldMaker11-Nov-03 9:11 
AnswerRe: Nice, but....VC6 version? Pin
Dan Peverill10-Nov-03 11:38
Dan Peverill10-Nov-03 11:38 
AnswerRe: Nice, but....VC6 version? Pin
WillemM9-Jan-04 7:07
WillemM9-Jan-04 7:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.