As part of the ongoing improvements to my text based adventure game, I decided to develop a retro style graphics engine to go with the text based aspect.

This meant having to upgrade the Console Application I had developed into a Windows Application without having to do a major rewrite of the engine; I did by creating methods which would complete the same job as the original Console method, but using a form instead of a console.

The central idea I had for my graphics engine would be to add a new string parameter to some data types and store the relative path to an image for that item. This would mean having to keep all the images in the file system with the game, so hopefully we can keep the size down.
Since I have moved the player command interface from a never ending loop to a regular method with a string input (so the UI remains responsive) I simply added a new method at the footer of the player input which triggers a drawing of the room.

The drawing method starts by checking if the Room/Building has a background image, then paints a panel with that image. If there is no image then it retains the previous. Then the method iterates through every item, enemy and NPC, and for every one of those items that has a valid image, it creates a picturebox element and adds it as a control to the panel.

Through this simplicity the game was able to build environments quite dynamically, when items are picked up or enemies killed the environment was updated.
The biggest issue I had was with placement, originally thought that I would pre-define some locations and the game would just place whatever data item at that place, however this meant that there could only be a finite number of images on the screen, and that no matter what the screen the images would always appear in the same place, which would not always make sense.

So I decided I could actually incorporate image painting into the world editor. If I extended the room editor form with a similar panel I could draw the room, and all I would need to do would be to add functionality to the PictureBox elements to be able to position them, then when the room is saved to scan through the locations of the panel, and assign the Location attribute of the PictureBox back to the data item. For this I had to add a Point attribute to the data items, and that meant having to add in System.Windows.Drawing reference to the project.

So originally I designed that when each picturebox was made, it had a mousemove method which would reposition the picturebox to the position of the mouse
public void DragNDrop_MouseUp(object sender, MouseEventArgs e)
{
PictureBox picBox = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
picBox .Location = new Point(e.X, e.Y);
}
}

However there was a problem. The mouse event argument “e” had both X and Y attributes which held coodinates relative to that control. So when I started to move the control it would send the coodinates from within the panel, which would move the picturebox to the mouse location within the panel. But when the cursor was inside the picturebox the coodinates would be sent from within that control so all at once the picturebox was being sent coodinates to within the panel, and from within itself, but in both cases was being moved within the panel. Obviously this was a problem.

The solution, was to not use the global coodinates of the MouseEventArgs. It also passes in a Location attribute, which holds how far the mouse has moved in the X and Y axis. This meant that we could figure out the new position of the PictureBox if we took how far the mouse had moved and added it onto the original position, as below
public void DragNDrop_MouseUp(object sender, MouseEventArgs e)
{
PictureBox picBox = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
int X = picBox.Location.X + e.Location.X;
int Y = picBox.Location.Y + e.Location.Y;

picBox.Location = new Point(X, Y);
}
}

This meant that the world designer would now draw the the room, and the user could paint it as they saw fit, and on saving the game would save the location of the data item so when the game is played, the environment was presented in a much more suitable fashion.

There is still an issue of items being carried. Default items in the inventory will not store Point data, and when an item is picked up and dropped in another room it will retain it’s original position, which may not always make sense but one step at a time.