GameUtil Class Library + Demo

wyrd

Senior Contributor
Joined
Aug 23, 2002
Messages
1,405
Location
California
For latest news on this project, please visit www.danpeverill.com. Feel free to e-mail me at dan@danpeverill.com with any questions or comments that you may have.

View Demo Screenshot.

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 succedded. As a fellow game hobbiest, 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 fullscreen 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 may be a bit confusing at first. It's 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 extention 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 editting 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 DDGameGraphic("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 gameloop 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);<br>
}

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.
 

Attachments

Last edited:
I'm looking for suggestions for the next version. So far I'm considering the following;

- Allow DDGameSurface to be treated as a container for DDWindows. The DDWindow will include z-ordering, hide/show, draw, and transparency options. The DDWindow will also act as its own container to allow child windows.

- An AI namespace which will include generic A* algorithms and generic Finite State Machines (FSM).
 
Back
Top