So as some of you know, I have been working on a top down 2D game, and finally (with the help of some great resources!) managed to get some procedural terrain generation happening.For those who don't know, I will just sum it up, by showing you a video of where the game is up to right now.http://www.youtube.com/v/8k8oLnWopMw?version=3&hl=en_US&start=

As you can see, there is no auto-tiling/tile transitions. And despite spending hours upon hours googling for resources on how to go about creating an auto-tile system, I still find myself sitting in my chair, scratching my head as to how I can implement an auto-tiling system efficiently.

Now I don't know if it's because I have the flu, have had very bad sleep, haven't been eating properly, am stressed from work, am sore from the gym and have been dedicating just about every moment of my minimal free time to programming research and work...but I read those links, and for some reason I can't seem to fully understand them, I kind of understand, but without some kind of source code example, I find myself thinking "huh?"

I just feel stupid that I can't seem to understand how to implement this when so many other people eagerly point out that link and the other links as being the best resources, then saying they've implemented the system within 2 hours. I've been trying to understand it for 2 days and haven't gotten anywhere, it's frustrating and disheartening that I can't even understand something that is apparently so simple

I really don't even know what to ask, the only way I could understand it is to see source code, or pseudocode.

Could anybody please explain the implementation side of thigns better than those articles, or post example code or pseudocode?

Your help will be greatly appreciated, and I think when I understand it, I will be writing a tutorial for others to understand it too.

If you want to create the transistions of terrain you have 3 option i know about:- Create an texture for every possible transistion, and place them at borders.- Create an texture programmaticly for every possible transistion using noise at startup, and place them at borders.- Change your terrain genaration, so an tile has an value for all terrain types, and then just mix all textures when you need to draw.

If you have an preference i can try to explain it more.What exactly is the problem, where are you currently at?

- After I generate my byte[][] (0 - deep water, 1 - midwater, 2, shallowater, 3 wetsand etc) I do yet another iteration through the byte array within the terrain generation class, and do the neighbour checking before re-assigning values to the byte[][] (I would probably have to change the byte[][] back to int[][] to compensate for number of tiles, and that would limit the size of map generation, however it is capable of doing 540,000,000 tiles, so I don't think that will be an issue )If a player digs a tile out of the map later, then the WorldRenderer will change the number at that array cell to cator for the tile change.

- In my WorldRenderer class (where I actually draw the tiles based on the byte at the current iteration through the byte[][]), I could call upon the auto-tile generation for every tile within the viewport, realtime. However I am worried this will cause performance issues, I won't know until I try.

My problem is that I don't know how to actually write the auto-tile method, I don't know if I should write a whole new class with it's own methods or create a method within my WorldRenderer class, or within my terraingeneration class. I just seem to be brain dead lol.

I attempted to do some kind of for loop earlier within the WorldRenderer, but it would make a horrible mess of my code, as there would be if, if else, statements everywhere.

Perhaps I just need to sleep on it, try and come back to it when I am not feeling crappy

Well, I think that instead of modifying your original array, you could make a new one that tells which tiles around it are need to be auto-tiled. After rendering how you are right now, go through it a second time, and then render the correct auto-tile by checking the tiles in the positions around it.

Can you show your terrain assignment code then?It would be much easyer to help.

Certainly. This is my current code to render through the portion of the map that is within the viewport:x0 = bottom left of viewportx1 = bottom right of viewporty0 = top left of viewporty1 = top right of viewport

As for where I am up to. Based on what I had read in those links, I wanted to work out a method which does as those links say, so it adds up values of surrounding tiles to create a tile ID of sorts which would be then used to reference a specific sprite, then use that sprite ID when I do a batch.draw in the render() method.

I have a bit more clarity this morning, I think yesterday my mind was off with the fairies and getting slammed with an internal hammer at the same time, so i'll get cracking soon enough and see what I can come up with.

Also Geemili, I will thoroughly check out your code a bit more later. I read through this morning and I was impressed by the amount of effort you have gone through to help me, I appreciate that, because that is exactly the help I was after

The transition information for a single terrain type need only use 8-bits of data (4 bits for the edges and 4 bits for the corners) which fits conveniently into a single byte

While I understand the concept, and it's an excellent one, I just don't know how to store the information in a single byte.I think it's just because I don't understand how to use/create bitwise operations.Now I know how to use bitwise operations, the operators are straight forward...If I did 01000001 | 00011000 it would equal 01011001If I did 01000001 & 01011000 it would equal 01000000If I did 01010101 ^ 10101010 it would equal 11111111The ~ operator I haven't looked into too much, seemed a bit more complicated and not applicable.

...However I still don't know how to store the information

There is a post here which goes through the technique vaguely, but due to my lack of knowledge of bitwise operations, i'm scratching my head.

I am writing down how I think it should be done now, and trying to put the process into play. Hopefully I end up with a good result by the end of the day!

publicintgetTileFrame(){// What tile transition we should have.intresult = 0;

// If tile above, if tile down, etc.if(up) result += UP;if(right) result += RIGHT;if(down) result += DOWN;if(left) result += LEFT;

// This checks for diagonalsif(result == UP + RIGHT + DOWN + LEFT){if(upLeft) result += UP_LEFT;if(upRight) result += UP_RIGHT;if(downRight) result += DOWN_RIGHT;if(downLeft) result += DOWN_LEFT; }returnresult; }

In the example that I gave you, I used bitwise operations. The '&' operator is a bitwise operator that takes the bits and does this:

1 2

dec: 2 & 3 = 2binary: 10 & 11 = 10

So, you can store multiple values in a number, up to 8 booleans in a byte.

However, in Java, it isn't quite so simple. Bytes in Java range from -127 to 128 (inclusive), so it is more difficult* to store 8 booleans in a byte, but possible by writing the numbers in hexadecimal instead of decimal.

So, instead of this:

1

byteaByte = (byte) 255;

You would have to use this:

1

byteaByte = (byte) 0xff;

But thats only if you want to use only a single byte. Otherwise, you can just use the code in my example.

*In C++/C there are primitives called ubytes, which stands for unsigned byte. Unsigned bytes differ from signed bytes because they range from 0 to 255 (inclusive), or basically don't have negatives. Java does not have unsigned numbers.

I haven't yet implemented anything just yet, but I can see how it all should work (I guess I don't just want to copy/paste your code without really fully understanding what is happening first).

I like your method LongArmX as it's nice and short and sweet, that is what I am aiming for.It's simplified and makes perfect sense. I don't think it takes into account any tile precendence like Geemili has in his code, but still a great simple example The result would refer to a specific tile ID which could then be used to determine what sprite to draw when I do the batch.draw method.

Now that I understand bitwise operators, I can now see where you have used them Geemili, for example:

1

if(transitionTile[x][y] & 1==1)

So in this case if the transitionTile[ x ][ y ] was equal to 8 the following would occur because of the & bitwise operator

So it's saying if 1000 and 1000 match one another, then the result is 8.

Am I correct? Or am I way off?

Be careful, because 1xxx & 1000 will still == 1000, no matter what the x's are, so it is not a test for matching the entire number.However, it is a perfect test of if that first bit matches the first bit of the second number. It is a bitwise operation.

In the example that I gave you, I used bitwise operations. The '&' operator is a bitwise operator that takes the bits and does this:

1 2

dec: 2 & 3 = 2binary: 10 & 11 = 10

So, you can store multiple values in a number, up to 8 booleans in a byte.

However, in Java, it isn't quite so simple. Bytes in Java range from -127 to 128 (inclusive), so it is more difficult* to store 8 booleans in a byte, but possible by writing the numbers in hexadecimal instead of decimal.

So, instead of this:

1

byteaByte = (byte) 255;

You would have to use this:

1

byteaByte = (byte) 0xff;

But thats only if you want to use only a single byte. Otherwise, you can just use the code in my example.

I would love to learn how to do it just using a single byte, the more optimization techniques I know, the better! Especially if I plan to have this working on Android and IOS devices too

I put my code into eclipse and fixed some things up to see if it would work, and as it turns out, it is not possible to store all the information in one byte in Java. The smallest type of number you could use is a short, but I'm not sure how much it would affect performance.

I have never done this before, but I was wondering if you could use texture splatting to mix two tiles together. For example, you have a grass tile and a sand tile next to each other. Take the tiles, splat the textures together to form a new grassy sand texture, assign the texture to a tile in between the sand and grass and there you go, you don't have to actually make the textures yourself, the game makes them for you so you can have lots of combinations. Again, I have no idea how this really works so I don't know if its expensive and slow. Just thought I'd share my 2¢!

When I have a more finished working version, I will show the code, just in case anybody has any suggestions for improvement

For now, I will describe the steps the program takes:

1. Inside of the Render() method, I call on a method called drawBaseTiles(); which does an x and y FOR loop through the tiles in the viewport (and a little just outside the viewport to prevent "popping" tiles), rendering tiles based on the byte value at the current array index using a switch statement to decide what tile to render.2. After the base method runs, I run yet another method to draw the transition tiles called drawTransitionTile();3. drawTransitionTile() performs the same loops through the tiles currently on the viewport that the drawBaseTiles(); method does, only does not use a switch statement, it just calls upon another method within the loop called selectSprite(x, y);4. selectSprite(x, y); initializes a "result" variable with the result of another method called getTileType(x,y);4. getTileType(x, y); first calls upon another method, which is called checkNeighbours(x, y); which serves to turn some boolean values to true depending on if the neighbouring tiles equal the current tile or not.5. After setting up, up_right, right, down_right, down, down_left, left, up_left to true/false (default value is false) the method finishes and the checkNeighbours(x,y); method continues with some conditional statements which basically say "if true, result += .... (1, 2, 4, 8, 16, 32, 64 or 128)". The method then returns that value back to selectSprite(x,y);6. selectSprite(x,y); then uses the returned value to choose from a list of sprites with the use of a switch statement with a whole bunch of cases (if I used if statements, I imagine it could be painful to read).7. Once a case matches, it does a batch.draw() of a specific sprite.

I haven't yet incorporated precedence rendering just yet, but it's in my head, and I don't think it will be very hard to do, but like everything, it always seems easy until you go to do it

Now it may not be the most effective way of doing things, but I did a big clean up of my code today to make it more organised, putting pieces of code into methods, separating code, leaving large title-like comments in the code such as:

UPDATE:At the moment, I have 2 textureAtlas's now, and I think it is causing some stutter. The framerate remains steady 61-60, but the time for each frame itself is sporatically slow.Because of this, I've quickly looked at using spriteCache in my code too. I'm not sure if I have to use it in combination with spritebatch just yet, but that is research for another day.But, progress was made today, I knew it would happen, just had to be patient with myself. I'll make a new post with source code link and maybe a video when I get it sorted

Here is a video showing off progress so far, it is mainly about the auto-tiling, but i've put some zoom functionality in there and fixed up mouse coordinates (needed to do a bit of research to convert them to world coordinates, rather than screen coordinates).Note that the zoom functionality most likely won't be used in the final game, it's just used to show off the terrain. Manual zooming plays no part in actual gameplay, therefore will only be used for testing. Automatic zooming based on height may play a part however. Either that, or the higher the player is, the further he will be able to move his mouse away from his player.I also decided to see how it'd perform on my Galaxy S3 phone, so had to work out gesture controls etc for it to work properly, and it works fine just to show off.

I have quite a lot of Auto-tile textures to do, so at the moment, my main goal was to get auto-tiling working, and to understand the process of getting it to work.Later on, I will work on the 250+ 32x32 textures and animations Thanks to the input some of you guys have given me, it gave me a bit more of an insight. I ended up doing my auto-tiling differently to what was suggested, and i'll see if I can somehow post the code on here to show you guys what i've done.

On a side note, I have discovered that having an alcoholic drink when you can't focus actually helps you focus, I guess it cuts out all the annoying crap from your mind and lets you focus on one thing at a time. I guess this is why Russians are some of the best programmers in the world, they don't drink Coffee, they drink Vodka at work, them clever cookies!

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org