Platformer

random level layout.png
I changed the Everyday Tower project quite a bit. I kept adding stuff and settled on something simple but with actual gameplay. Right now it is a simple platformer but the levels are randomly generated using a Hamiltonian Path. The way the code is currently written, I can generate levels with n² rooms. The variable n = 4 in the image above. Each level is linear, with one start point and one end point, and the path will cross each vertex (in this case, each room) exactly once. This code works in the following manner:

Generate a list of Hamilton Path coordinates.

These are stored as a series of x,y coordinates from the starting room to the ending room. This code works by starting with a linear connection of rooms from the top to bottom, then uses a script to make a series of attempts at modifying this path in ways that still adhere to the rules of a Hamilton Path. The above layout (random level layout.png) was generated using these coordinates:
[[3,0],[2,0],[1,0],[0,0],[0,1],[0,2],[0,3],[1,3],
 [2,3],[3,3],[3,2],[3,1],[2,1],[2,2],[1,2],[1,1]]

If the origin room [0,0] is in the top left corner of the above image, then you can see the starting room is in the top right, which then follows the list of connecting rooms until the final room, which is [1,1].

Once this list of coordinates has been generated, it is now possible to determine where the walls will be placed.

Derive wall placement

The path coordinates are sent to a script that will determine where walls should be placed in each room. This information is derived by looking for changes in the x and y coordinates as we progress from the starting room to the ending room. Whenever the x or y value is changed, the script will mark that as a path into the adjacent room. This information is stored like this:
[[0,0,0,1],
 [0,1,0,1],
 [0,1,0,1],
 [0,1,1,0],
 [1,0,1,0],
 [1,0,1,0],
 [1,1,0,0],
 [0,1,0,1],
 [0,1,0,1],
 [1,0,0,1],
 [1,0,1,0],
 [0,0,1,1],
 [0,1,1,0],
 [1,0,0,1],
 [1,1,0,0],
 [0,0,1,0]]
The order of this array is the same as the path array, but each array contains four booleans. The index of these boolean values determines whether or not there is a wall. They are ordered uprightdownleft. For example, the room at [2,0] in the image (second position in the array) has walls on the top and bottom and a path going left and right. Its corresponding wall data would be [0,1,0,1] . The 1 indicates a path and 0 indicates a wall, so [wallpathwallpath] would be [0,1,0,1] in the array. It is again important to note that the order of this array is the exact same order as the solution path. Because of this, the array must be reordered from left to right, top to bottom before proceeding.

Reorder the array

The array of wall data is reordered starting with room [0,0] and ending with room [n,n] where n is the size of the dungeon. The code that actually builds the level works from 0 to n in both directions, so the array must be reordered so that the walls are built correctly.

Build each dungeon room

[[0,0,0,0,u,u,0,0,0,0],
 [0,1,1,1,1,1,1,1,1,0],
 [0,1,1,1,1,1,1,1,1,0],
 [l,1,1,1,2,1,1,1,1,r],
 [l,1,1,1,1,1,1,1,1,r],
 [0,1,1,1,1,1,1,1,1,0],
 [0,1,1,1,1,1,1,1,1,0],
 [0,0,0,0,d,d,0,0,0,0]]

The above 2D array is the base template for a dungeon room. Each room is 10 tiles wide and 8 tiles tall. The variables u, r, d, and l are set to 1 or 0 depending on the wall data. A 0 indicates an area where the code will place a wall tile, and 1 is left open. The 2 is the player spawn point, which is used once and then discarded.

This part of the code is pretty scrappy but using a 2D array allows for an easy visual representation of a single room. It will likely be modified soon to use a more rigid data structure so that additional information (e.g. enemies, powerups, switches, elevators, etc.) can be stored and retrieved easily.

Leave a Reply

Your email address will not be published. Required fields are marked *