Developer

Game mapping provides an introduction to GDI+

GDI+ offers an easy mechanism for graphics programming in .NET. Follow this quick example using a map for an Internet-based game to get a handle on the design and the GDI+ classes.


I'm working on an Internet-based turn-style fantasy game called Unbound for GenreOnline.com. One of the most important parts of an adventure game's turn sheet is the map. The map makes much of the statistical information given out at a player’s turn more understandable by presenting it visually. In .NET, you can employ graphics device interface plus (GDI+) to program the graphic elements—in this case, the map. But developers who are familiar with GDI in Visual Studio 6.0 will find that GDI+ is very different in .NET.

Since this is a turn-based game, you don’t need to generate the maps in real time—which is fortunate, since there is a tremendous amount of information to present. Figure A shows the information we'll transfer into a map like the one in Figure B.

Figure A
A subset of the Unbound data model


Figure B
A finished Unbound map


Essentially, this process calls for four operations:
  1. Open a template for a new map—basically hex paper.
  2. Place icons in the right places on the map.
  3. Write the title on the map.
  4. Save the map where it can be found on the Web server.

ASP.NET Web Matrix
Many IT pros are amazed that Microsoft has made parts of the .NET initiative available for free. The ASP.NET Web Matrix tool is designed to make it easy to code simple apps. Learn how to put this free tool to good use in your development efforts.

The design
To handle these four operations, we'll add a class called MapImage to the Unbound.MapEngine namespace. In the constructor, we'll load the image into a GDI+ Graphics object. Then, we'll add three methods: PlaceIcon, WriteTitle, and SaveMap.

Part of the goal here is simplicity. Aside from some simple error handling, we won't do anything very complex. Since this will run in the background as part of a Windows service, we don’t have too many concerns about performance or Enterprise Services.

The code
To begin, we will create a new class library project in Visual Studio .NET. By default, it will include the System namespace; we need to include the GDI+ namespaces, as well:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;


Now, we need to get a few objects that will represent our image. First, we'll grab a Bitmap object that will load the hex paper and save the finished map. Next, we need a Graphics object that we will actually manipulate with GDI+. We'll load up those two objects in the class constructor:
protected Graphics MapBase;
protected Bitmap newBitmap;
public MapImage()
{
    //Load the image up here
    newBitmap = new Bitmap("c:\\map\\map.bmp");
    MapBase = Graphics.FromImage(newBitmap);
}


The PlaceIcon() method will get an icon from the icon library (essentially just a filename in the map directory on our server) and place it on the Bitmap object at a specified set of coordinates:
public void PlaceIcon(float xCoordinate, float yCoordinate,
string iconType)
{
    Bitmap iconImage = new Bitmap("c:\\map\\" +
iconType + ".bmp");
    MapBase.DrawImage(iconImage,xCoordinate, yCoordinate);
}


To write text with the WriteTitle() method, we'll use one of the well-constructed FontFamily collections of .NET, which give VB programmers unprecedented access to the font library. Then, we'll build a new Font object and use another in the collection of Draw methods to place our text:
public void WriteTitle(string textToWrite)
{
    FontFamily serifFontFamily = new
FontFamily (GenericFontFamilies.Serif);
    Font textFont = new Font(serifFontFamily, 12);
    MapBase.DrawString(textToWrite,textFont,
new solidBrush(Color.Black),
new RectangleF(100, 100, 250, 350));
}


Finally, we'll save the image to a file using our instance of the Bitmap object. We can then dispose of our memory-hogging Bitmap and Graphics objects:
public void SaveMap(string fileName)
{
    newBitmap.Save("c:\\map\\" + fileName +
".bmp", ImageFormat.Bmp);
    newBitmap.Dispose();
    MapBase.Dispose();
}


Conclusion
The GDI+ classes in the System.Drawing namespace give Windows programmers great functionality that was lacking in previous versions of VB, or even C++. While C++ programmers could access drawing, it was much more complex. GDI+ provides the functionality you need to create complex effects and brings a whole new dimension to class library development in the Windows world.

Editor's Picks