Programming: Pathfinding Pt. 2 (Tilesets)

In the previous post, I had setup the need for modular functions to randomly generate functional wall collisions and corresponding art. 

The first setup is to revise how the background images are being imported into memory. Rather than a static background, I'll import each individual tile as into separate lists: "Walls" and "Floors". This is done as part of the "Background" class.

With other graphical tilesets setup in a similar template, I can easily change the flavor of the background.

Next is to revisit the "Tiles" class used for defining the functional "Wall" lists. The tiles have to be selected to match the directional rules within the wall list. For example, tile (x, 0) is within the "Wall" list, and such have a "Wall" tile. There are x-neighboring tiles (x-1, 0) and (x+1, 0) also within the "Wall" list, but (x, 1) is not. Finally, the position of (x, 0) is at the top of the screen, so the selected graphical tile is number 7. 

I've painstakingly went through every single condition to generate accurate tilesets for all possibilities. These rules will be checked by scanning every tile within the (17 x 13) grid, and adding a graphical tile into a "self.map_list". After adding all the tiles into the "self.map_list", the next job is to draw them out tile by tile.

Screen Scrolling v.2 

From the "Scrolling Backgrounds Pt. 2" post, I described how the background art is shifted around the game window to provide "motion". Each screen is stored as a separate 17 x 13 set of tiles within the "self.map_tiles" dictionary. The "Background" class stores the screen position (x, y), which is the key to the unique set of "Wall" tiles.  The "Wall" list is reiterated for each level key, which creates the "self.map_list" dictionary of matching tile graphics.  

Unlike the static background from "Scrolling Backgrounds Pt. 2", the entire game map is not drawn into memory. The solution could be to every draw tile for every screen constantly, but that would be inefficient. It would be far more efficient to only draw what is needed. By adapting the "self.scroll" attribute from the "Background" class, I can reuse the boundary conditions to trigger the screen scrolling and use the screen value as the key for deciding which screens to draw.

  • If "self.scroll" is False, the "Tile" class will draw all tiles for the current screen value (0, 0).
  • If "self.scroll" is True; the "Background" class will store the destination screen value (0, 1). Both screens (0, 0) & (0, 1) are drawn simultaneously during the screen scroll transition. The destination screen is offset by one screen width; such that the old screen is pushed off completely and the destination screen is centered. After the displacement, the "Tile" screen value is updated and the "self.scroll" attribute is switched off. 

Randomness

With all the visuals set up, I can add some more variation into the level design. Below are a series of obstacles defined by tile size:

  • Rock: 1 x 1
  • Boulder: 2 x 2
  • Row: 1 x 3 
  • Corner: (1 x 2) + 1
  • Tetris: (1 x 3) + 1 
  • Cross: (+/-1, +/- 1)
These can be defined as a list with a randomly generated integers, set in a list that is appended to the "Walls". For testing the tiles I've plotted them all out below. I'll need a bit more code to randomize them and combine into a natural looking level.


All the walls are functional, but now I need to the actual pathfinding to make the enemy AI obey them. 

Comments