Here we go again. This time I have made a rather simple example cap, showing one scope of application for both, arrays and hash tables, and setting them side by side, to compare them and see, where they are of advantage.
NEW VERSION (19.02.2011):
Array_Hash.cap
You may want to first download the cap and then switch back and forth between Construct and this post.
I. Array
I.1 Demands
The base for the example is a map editor. Imagine you want to create one for your game. It is tile-based, so you know the exact dimensions of the map and you know the tile dimensions. In this example the map has 256x256px, and the tiles have 64x64px. That's a map size of 4x4 in tiles.
You might want to have a little variation for the tiles as well. In this example, every tile has 4 animation frames, which can be freely selected.
Now we need to manage and save the informations. The easiest way is to save the frame number of a tile to its position expressed in tiles. That does give the advantage that we could later change the size of the tiles without affecting the map layout. This is a perfect job for an array.
I.2 Effect
Run the cap now and click on 'Array'. You will see a red-colored area. Use the mouse wheel to change the animation frame of the tiles. When satisfied, click on 'menu' and then on 'Save array'. Click 'menu' again and select 'Main menu' this time. Click 'Array' again. You will notice that your map is automatically loaded. Change some frames and select 'Load array'. It is reverted to its last saved state.
I.3 Cause
Have a look at the event sheet of the layout 'Array'. Open the group 'Array'.
Event 21 and its subevents are initializing the array. First it is set to 4 in x-dimension and 4 in y-dimension. Then every "cell" of the array (16 in total) is set to the value 1. This is needed, because the first animation frame is 1, but the array is initialized to 0. The next event loads a saved array file, if there is one. This is just a convenience. The last subevent loops through the map and creates the 4x4 tiles.
Event 26 and its subevents changes the frames of the tiles and updates the array with the new frame numbers.
Open the group 'Menu'. Events 16 and 19 take care of loading and saving the array. When loading, it is needed to loop through all tiles and set the frame number to the one stored in the array.
For all accessing of array "cells", some simple math is used to get the tile position. The map starts at (0, 32), a tile has a size of 64x64 and its hotspot is centered. Therefore the tile at array value {1, 1} is located at (32, 64) in pixel values. With (mapobject.X - 32) / 64 + 1 we get (0) / 64 + 1 = 1, and with (mapobject.Y - 64) / 64 + 1 its 1 again, as expected. The tile at array value {3, 4} is located at (160, 256). Just try the math above with that pixel values, you will get the correct tile position. You just need to substract all offsets from the origin, then divide by the tile's size and add 1, to shift the range from [0, 3] to [1, 4].
II. Hash Table
II.1 Demands
Again the base for this example is a map editor. But in difference to the first example it now is object-based. A map object can be placed anywhere on the map, not just on a grid, and it can be deleted or moved. The map size still is 256x256px, and the map objects have a size of 64x64px. And all objects also have the same variations as in the first example.
To manage and save the informations, we need something to store the coordinates of an object and its animation frame, and those informations may change at any time, or the object may even be deleted. Using an array as we did in the first example is not very effective. First, we would need to make it have 256x256 cells, even if we only place one object in the map. Second, everytime an object is moved we sould need to clear one cell and set another. Third, if two objects are placed at the same coordinates we couldn't store the informations for the second one, the cell is already used for the first one.
It is much better to have an object-oriented approach. This is a good (but not perfect) job for a hash table.
II.2 Effect
Run the cap now and click on 'Hash Table'. You will see the empty map area and some text in the upper left. This text will keep you informed over your objects. Left-click anywhere on the map to create an object. Hold the shift-key and click and hold the left mouse button over an object to change its position. Right-click over an object to delete it. Use the mouse wheel when over an object to change its animation frame. When satisfied, click on 'menu' and then on 'Save hash table'. Click on 'menu' again and select 'Main menu'. Click 'Hash Table' again. Click on 'menu' and select 'Load hash table'. Your last saved map is restored.
II.3 Cause
Have a look at the event sheet of the layout 'Hash Table'. Open the group 'Hash Table'.
Event 23 initializes the hash table by inserting the key 'pid' with the value 0. Event 32 creates a new map object, sets the object's pid to the value of the hash table's 'pid', raises the hash table's 'pid' by 1 and inserts a new key into the hash table. This key represents the new object and it has the following structure:
key = object's pid, value = a string in the form objectXxobjectY;animationframe (e.g. "128x64;3")
Event 28 moves an object to a new position. The value of the key that corresponds to the object's pid is set to the new position, by just creating a string from the coordinates and the frame number again.
Event 29 deletes an object and the key that corresponds to the object's pid.
Events 30 and 31 change the animation frame of an object and sets the value of the corresponding key to a string created from the coordinates and the frame number again.
Open the group 'Menu'. Event 16 and its subevents take care of loading and creating the map from a file. If there is no file, the content of the hash table keeps its current state, else it is replaced by the data from the file. Either way, all objects on the map are deleted. We then loop through every key that is not named "pid" and create an object based on the string value of the key. The coordinates and the frame number are retrieved using GetToken, which returns a substring of a string by interpreting a given letter as a delimiter. For the coordinates the delimiter is "x" and for the frame number the delimiter is ";". See the comment in event 20 for more information.
I'm working on other examples for hash table use, so check this thread from time to time.