While we could manually change all the tiles to look correct around the edges and coast it’s easiest to use math. Let’s learn about bit shifting to create the correct sprite IDs we’ll need.
- [Voiceover] So at this point, we're gonna wanna take a look, at some of the ways that we can autotile our tile map. Autotiling is when we look at the neighbor tiles and give the individual tile a different sprite. A lot of the times you'll see this as having rounded corners and it helps break up the repetition you might see in tile-based games. In order to do this however, we're gonna need to figure out a way to calculate the values for each of the neighbor tiles. You'll remember, when we created our tile class, that we set up four different positions for the neighbors array.
Here, you can see an example of how this will work. Each tile actually has eight neighbors, but to keep our math simple, we're simply gonna focus on four neighbors. The top, the right, the bottom and the left. Now one of the ways that we can quickly represent this actually by converting these values into a binary number. A binary number represents a value using two digits, zero and one. Sometimes you'll hear binary represented as a base two counting system.
Each one in binary represent a power of two, and each zero represents a zero. But how does this relate to our tiles? Let's take a quick look at how binary works. Here we're gonna look at a 4-bit number. A 4-bit number is represented by four characters. If we start at zero, you'll see that the binary value for zero, is simply zero, zero, zero, zero. If we add one, we'll get to the value of one. Now here's the trick, if we add one again, to our binary number, you'll notice that the one now shifts over to the left.
This works exactly like our own number system, our system is a 10-based number system, which means that once we get past 10 characters the remainder is carried over to the next digit to the left. Our numbers go from zero to nine, so anything over 10 resets the value to zero and one goes to the left. In binary, anything that goes over one, resets the value to zero and moves the digit over to the left. When we go from two to three, we simply add one and get zero, zero, one, one.
And when we get to four, if we add one, one plus one will be higher than one so it'll set it to zero. The next value will go to zero and the one will be carried over. It took me a little while to wrap my head around it but once I got it, it made a lot of sense. Now let's take a look at our autotile template. Each 4-bit value corresponds to a position in the autotile template. The largest number we can have as a 4-bit number is 16. And since it's zero based, you'll see on the far left we start with zero and on the right we end with 15.
Below each of these tiles you'll see we have a binary representation. And if you go from one to two to three to four and so on, one gets shifted over to the left, each time we increase the value by one. This technique for being able to figure out a position in a binary number is called bit shifting. And it's incredibly fast. It's also used a lot in games. Well we're not gonna go into the details of how bit shifting works. I wanted to at least illustrate the foundation of how this concept is played out and I'll show you really quickly how we can actually leverage it in our own tile map.
Now let's go back to our example of our neighbor tiles and take a look. If we start with our top tile, you'll see that the first position in binary equals one. If we look at our left tile, you'll see that the second position is one. If we look at our right tile, the third position. And the bottom tile, is the fourth. If we go ahead and loop through each of our neighbors in a particular order, and test to see whether a neighbor exists, by setting it to one. Or if it doesn't exist, setting it to zero.
We're able to create a binary number. In this example here, if the neighbor exists on all sides, we're gonna set this tile to 15. If no neighbors existed, this tile would be zero. It's incredibly important how we actually go about calculating each of the sides. If you remember back to how we created the original tile class, we set up an enum for each of the sides in the order that we want to add them. We're gonna do a trick. While this is the not the most efficient way to do it, it'll help you get a good foundation of how binary works.
The trick is that we're gonna make a string to represent the binary value, and then we'll use the convert class to turn it into an int. In order to make this string, we're gonna need to go from left to right. And that's why the enum sides is ordered from bottom to right to left to top. And as we go through and test out each side, setting a one or a zero, depending on if there is a neighbor or not. We'll be able to take this string and quickly turn it into an int. And this is the basis for how autotiling systems work.
And if you were to use eight sides, you would use an 8-bit number. And while we won't be able to get into eight sided autiling in this course, there are a lot of resources out there that can help you, once you understand the basic foundation.
- Setting up the project
- Creating the tile, map, and map tester classes
- Visualizing the map
- Creating a moving camera
- Autotiling and bit shifting
- Decorating the map