Image

Generating Maps From Image Files

by Mr. Hexagon


.: What's this? :.
This is intended for people who are already familiar with the basics of custom maps in MMF.
It is a method of generating maps without the use of an array.
Instead of arrays, the map information is stored in an image file.
The map is called upon at the beginning of the level and all evidence of the extrapolation is destroyed.

Example can be downloaded at the bottom of the page.

Image


.: What's the point? :.
Reason 1: Avoiding Redundancy
Most image editors already have well-developed features. Tools like circle, rectangle, line, and paint bucket. These tools are not only useful in making pictures, but also useful when painting maps. Not to mention, the ability to undo and redo or copy and paste is handy as hell. Yes, these are all features you could implement into a map editor of your own, sure, but why waste your time? The tools of an image editor have undergone the process of perfection since the 1980's. More than 30 years of time-tested tools versus the couple of days your map editor has been around? That's a very easy choice for me.

<Image

Reason 2: Avoiding Arrays
This method does not require arrays. Well, sort of. You don't have to bother with the Array Object, or anything similar. Image files ARE arrays, though. Each pixel of an image holds 3 values: Red, Green, and Blue. This can range from 0 to 255. You could theoretically have 256 different tiles, with 256 different attributes, and still have another 256 values to use, for say another layer of tiles with other stuff. This is more than enough information capacity to create most maps.

Image



.: How's it done? :.

This is done in 6 simple steps.


PREPARATION PHASE
I. Make image in the image editor of choice.

Image

The colors you use determine what the tile types will be. For this example, only pure white and pure black is used. But other colors could be used for specific things.

Be careful! Exact colors matter. There is a difference with the color 255, 255, 255 (white) and 255, 255, 254 (slightly dimmer white). The computer can tell the difference even though your eyes can't! If you have the wrong colors here, your map will fail to load later.

Also take caution! File formats matter. There is a difference between jpg and png. For the purpose of the example, use png or bmp because these will not interfere with the accuracy of your map. JPG will artifact to compress size, but will mess with the original colors you picked. Again, if you have the wrong colors on this step, your map will not load.

You may want to zoom in as well. Each pixel will represent a tile of your map.

II. Place objects into frame.

Image

These are the required objects to make this engine go:

-Active Picture Object (APO)
-Pixel Object

-Counters:
Map Height
Map Width
Tilesize
Countdown

-Active Objects:
pixelcolor (finds coordinates to get pixel color)
paster (pastes into the background)
player (8 directional movement or w/e)

-Button to trigger map creation.


EVENT PHASE
III. Load the map image into the Active Picture Object.

Image

Start of Frame
-(Active Picture): New picture:Apppath$+map.png

IV. Set the constants to counters.

Image

This step is to allow more flexibility into the engine. There are many tile size preferences. We'll use 16x16 for this example, but could work with any size. The map size is then determined by the dimensions of the picture you loaded on step III.

Always
-(Map Width): Set Counter to (X Right(Active Picture - X Left(Active Picture))
-(Map Height): Set Counter to (Y Bottom(Active Picture - Y Top(Active Picture))
-(Tilesize): Set Counter to 16

V. Define the loops.

Image

The loops examine the image and decide how to build the map accordingly.

On loop row
+GetRedAt(Pixel Object, x(pixelcolor), Y(pixelcolor)) = GetRed(GetRGB(0,0,0)
-(pixelcolor): Set X Position to (X(pixelcolor)+1)
-(paster):Add backdrop as obstacle
-(paster):Set X position to (X(paster)+value(tilesize))
If the pixel on the image is black, paste into background, move paster and pixelcolor to next spot.

On loop row
+GetRedAt(Pixel Object, x(pixelcolor), Y(pixelcolor)) <> GetRed(GetRGB(0,0,0)
-(pixelcolor): Set X Position to (X(pixelcolor)+1)
-(paster):Set X position to (X(paster)+value(tilesize))
If the pixel on image is white, don't paste background, and move to next spot.

LoopIndex(row=value(map width)
-(paster): Set Y position to (Y(paster)+value(tilesize))
-(pixelcolor): Set Y position to (Y(pixelcolor)+1)
-(paster): Set X position to 0
-(pixelcolor): Set X position to 0
-Set loop row index to 0
-Subtract 1 from Countdown
If the paster is at the end of the row, move down a space, move back to the left, reset the loop, subtract from countdown.

VI. Destroy the evidence.


Image

After the map is constructed, destroy everything related to building the map so it won't take up space.

Countdown = 0
Destroy pixelcolor
Destroy paster
Destroy Pixel Object
Destroy Active Picture Object
Destroy Map Width counter
Destroy Map Height counter
Destroy Countdown counter
Set player position to x,y of whatever you want.

Set the button to start the countdown. Have the countdown start the row loop if it's greater than 0 and you're finished with the map maker.


.: What else? :.
Internal vs. External Images

Image

By using external image files, like the example, you provide a very simple way to allow players to build their own map. However, if you do not protect your original files, a clever hacker could build bridges and destroy obstacles of existing maps. Protecting external files is beyond the purpose of this article, though.

Internal image files provide much better protection. Simply replace the Active Picture Object with an Active Object. The trade off for protection is that you lose customization capacity.

A simple way to feature both custom levels and protected levels would be to us both internal and external methods. The extra coding will be worth the effort.


Barely Visible Color Differences and File Types

Image

When designing the map, it makes sense for each tile to be incrementally associated with a number. For example, grass = 1, water = 2, rock = 3, and so on. However, incrementally increasing the RGB value in this fashion is difficult on the eyes. 0,0,1 and 0,0,2 look the same. The obvious solution here would be to only use visibly different colors when drawing out a map, however, this only moves the problem to coding side of things. A new event searching for each specific pixel color to assign it a tile will eventually become tedious. This is a problem to be further explored (the solution may rely on an array). However, you can use this conundrum to your advantage.

Instead of searching for specific pixel colors in Step IV, you could search for a range of colors. Such generalization would let you take advantage of features within image editors like blur and anti-aliasing. This is useful because the tiles placed during this color range could also be randomized, making for a more natural effect when making hills, mountains, trees, etc.

This can also be combined with the attributes of each file type. Each image file type (and there are lots) as special qualities. For example, JPG files compress images to reduce file size, and the resulting image becomes smudgy and artifacted with random pixels. These compression smudges and artifacts would in turn show up in your map. There are creative paths to explore here.


Download Example
http://www.mediafire.com/?ez91mk8exaxexco


Post! Let me know your thoughts.
Questions and comments can also be emailed to misterhexagon@gmail.com

Note: Let me know if you want the original HTML file of this article.

Image