9-Slice Scaling For Tile Maps

Share on FacebookShare on Google+Tweet about this on TwitterShare on Reddit

I’m working on an isometric city simulation with procedurally generated terrain, and as I started to generate terrain, I ran into a bit of an issue.  I’m using the isometric tiles from Kenney (which are amazing), but I was struggling to think of a way to handle edges.  Take this island for example:

iso-island

You can see that on the left side, there’s some sloping that lets the sand tiles blend into the water tiles.  That’s great, but I wanted a programatic way to handle those kinds of transitions.  I thought of 9-slice scaling and thought that might be a solution.  If you’re unfamiliar with 9-slice scaling, this tutorial might explain how it works.  The basic idea is that you can take a rectangle, and divide its parts into 9 (4 corners, 4 edges, 1 middle), and through scaling those 9 parts, you can maintain the look no matter how big (or small) it is.

Terrain is kind of like that when you think of it.  The middle is the sand tile, the edges are the slopes into water, and the corners are little sand and water tiles that fit between the edges.  I’ve taken the 9 “slices” from the above screenshot and broken them out to show you what I mean:

9-slice-breakout

So what I wanted was some code that I could feed these 9 slices into, and from that, it would generate a rectangle of any size (2×2 minimum) using the corners and edges.  I’ve successfully done that, so I’ll show you how it’s done.  In this example, I’m going to be generating a 5 wide and 4 tall rectangle.

The first thing I’m going to do is define the slices array:

This array represents the indices (or names) of the tiles I want to use for the slices.  I used 1-9 as they are laid out on a number pad because it was easy for me to visualize.

The second thing I’m going to do is build out what I call the “master rows”.  This is basically three rows which when combined make up the final rectangle.  There’s a top row, middle row, and bottom row.  There will always be a single top and bottom row, but the middle row will potentially be repeated multiple times (or not at all in the case of a 2×2 square).

The code makes three master rows, and for each row, it uses the first slice (the corner or edge), then repeats the middle tile as many times as needed (width – 2) and then tacks on the last slice at the end.  After we have all the master rows build, we build the rows for the rectangle.

This section is similar to how we build out the master rows, but instead of repeating tiles, we’re repeating rows.  After this is run with 5 width and 4 height, it should output:

After you have that array, you can splice it into your map and that’s all it takes to build tile rectangles with border pieces like so:

9-slice example

I hope you found that helpful and it helps you during your next game build.  Full code is included below:

 

 

Leave a Reply

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