Alternative Binary Maps and Logic

From GPWiki
Jump to: navigation, search

How we build our maps

Prerequisites

  1. Knowledge of your preferred language
  2. Ability to draw images with your chosen language/API
  3. Know how to do basic reading and writing to files
  4. A well thought out plan for your maps.

Introduction

This page is for a more advanced type of RPG type map using binary bytes to conserve space and provide more information in your map file.

Further map understanding

Please read RPG map making for more information.

Quick Binary Info

Binary data is basically a character with any type of ASCII value, your not limited to 0-9, A-Z, a-z. Each byte can contain any number 0-255. Now if we wanted to store some information to load tile number 34 consecutivly 10 times we could do:

34,34,34,34,34,34,34,34,34,34

The total length of the data is 30 bytes (3*10).

Now lets do it in binary:

""""""""""

The length has been cut by a third and loading the data has become much more simple. When loading the map data all you need to do is convert each byte to it's ASCII value and you've got your tile number.

Saving and Loading Binary Maps

Although saving a map in binary will save space and time it does have it's limits. As noted above the max number that can be saved is 255 so you're limited to that. See Alternative_Binary_Maps_and_Logic#Numbers Greater than 255 in Binary

First thing to do is choose your map size 32x32, 64x64 or whatever your needs are. It's important to keep the exact width and height a standard so your program will not fail with an error. So say you have a map size of 5x5 tiles. The minimal map size will be (5 x 5) = 25 bytes.

For this example we'll say that tile # will be equal to the tile name:

Tile # - Type

  • 0 - Water
  • 1 - Grass

We'll make a simple Island, the map would render like so:

00000
01110
01110
01110
00000

So your binary data will end up looking like this(assume 0 is chr(0) and 1 is chr(1)):

0000001110011100111000000

There isn't much saving size wise using such low valued tile numbers but trust me once you get more than 9 tiles the savings will be emense.

You'll be able to load the map using this example in Visual Basic:

Dim MapData as string, i as integer
dim X as integer, Y as integer
dim Tile as integer, MapWidth as integer, MapHeight as integer

MapWidth = 5
MapHeight = 5

MapData=LoadMapFile(MapLocaion)

for i = 1 to len(MapData)
 Tile = Asc(Mid(MapData, i, 1)) 'get the ascii value of the byte
 Call PaintTile(Tile, X, Y) 'draw your tile
 X = X + 1 'increment our X value
 if X > MapWidth then X=0: Y = Y + 1 'if X is greater than the Map's Width Reset to 0 and Move our Y up
 if Y > MapHeight then exit for 'make sure our Y value isn't larger than our map
next i

And that my friends is a basic Binary map.

Advanced Binary Maps

More advanced maps use layers. This type of map would have an intial layer or background and another layer for, say, trees or mountains. The advantage with this type of map is reusability! You could use the same tree tile over grass, snow and sand tiles. Adding transparency to your tiles allows you to make one tile and "paint" it over the background. You won't have to make the same tree sitting on grass, snow or sand. In addition to the already noted advantage there is another: you could use any item on the second layer as an unwalkable area.

To accomplish this extra layer all you really need to do is add one extra byte per tile. This will, of course, double the size of our map but considering the amount of space we've already saved by using binary maps it still may be worth it to you. Using the same logic above we already know that each byte is a tile and using layers the following byte will be a tile that is painted over top of the previously painted tile.

Using our island example from above and assuming tile # 3 is a tree with a transparent region our new map could look like so:

00000000000013131300001313130000131313000000000000

We use 0 as a null tile in our second layer. If that byte is 0 then we'll know that there is no tile to paint on that second layer.

And using the same Visual Basic example code from above with a couple extra lines of code:

Dim MapData as string, i as integer
Dim X as integer, Y as integer
Dim Tile(1) as integer, MapWidth as integer, MapHeight as integer

MapWidth = 5
MapHeight = 5

MapData=LoadMapFile(MapLocaion)

for i = 1 to len(MapData)
 Tile(0) = Asc(Mid(MapData, i, 1)) 'get the ascii value of the byte on the background layer
 Call PaintTile(Tile(0), X, Y) 'draw your tile

 Tile(1) = Asc(Mid(MapData, i + 1, 1)) 'get the ascii value of the byte on the second layer
 If Tile(1) <> 0 Then Call PaintTileWithTransparentRegion(Tile(1), X, Y) 'draw your tile

 X = X + 1 'increment our X value
 If X > MapWidth Then X = 0: Y = Y + 1 'if X is greater than the Map's Width Reset to 0 and Move our Y up
 If Y > MapHeight Then exit for 'make sure our Y value isn't larger than our map

 i = i + 1
next i

Numbers Greater than 255 in Binary

This little bit of information could be useful. Using this method you could have roughly 65280 tiles at your disposal :)

The trick is to divide the tile number using a more compact method. The example below will allow you to store your tile number into two(2) binary bytes of data. Of course using this method will double the size of your map and if you use the layer example above will triple the size.

Where TileNum is your tile number:

b = TileNum
a = Int(b / 255)
b = TileNum - (a * 255)
TileNumConverted = chr(a) & chr(b)

And to get the number from the bytes:

TileByte1 = chr(0)
TileByte2 = chr(255)

a = Asc(TileByte1) * 255
b = Asc(TileByte2)

TileNum = a + b