[XNA/MG] Voxel Engine - 4 - Adding NoisesteemCreated with Sketch.

in gaming •  6 years ago 

 So.. our terrain looks good. But it's flat, and we want it to look more like a real terrain. 


But MonoGame doesn't have a noise Library. Thankfully, Auburns made one in C# that we can use. It's called FastNoise, and you can get it here ("FastNoise.cs"). Add it to your project, or create a new class and paste the script in it.

Now that you have a noise system in your project, you can open the "Terrain" class :

We will need two new variables.

int blockSize = 16;

This is the size for one block image. It gives the size of the rectangle and we use it like before to know where to put a block next to the other in pixels.

int worldOffset = 10;

This will be used to bring down or up the world, avoiding hidden blocks that are too high to be seen with the noise.


Now go to the "Draw" method :This time, the loops are X = 0 until X < 50 and Y = 0 until Y < 30. 

Remove everything inside the loop, we will change almost everything

Let's start by adding our noise system. The noise will be calculated for each position in the loops.

FastNoise noise = new FastNoise();

We implement a new noise System to use. This will be where we calculate values.

float noiseValue = (float)Math.Floor(noise.GetPerlin(x * 5, 0) * 100);

We store the value of the noise in a float. It will return a value between 0 and 1. That's why we use "100" to make it bigger and return a value in our pixel world. The "Math.Floor" part will make sure the value is rounded to the floor value. (Ex : 10,678 will be = 10). Finally, we want to get the noise at the x position of the loop, "the first position", and multiplied by 5 to avoid having values that are too close to each other. So we don't have to use more blocks to give a good shape. It is used as the Frequency. You can say that "100" is the Amplitude.

noiseValue = (float)-Math.Floor(noiseValue / blockSize) * blockSize;

The result will be returned as a negative value, that's why we use "-". We divide the value by the block size, and the floor value of what is returned is multiplied by the block size. This will give the position of the noise value in a 16x16 grid. (Or a blockSize x blockSize grid). Thats also what we will use to get the mouse position in the world grid to place and remove blocks. 


Now that we have our noise value, we can draw our terrain :

Just like before, we will draw between "Begin" and "End". And again, begin will have the world matrix.

We need 3 values. For each loop, we will use the actual X and Y positions of the block in the grid. And we also need the Y position of the block with the world offset added to it.

 

int actualX = x * blockSize;

Just like before, we multiply the actual X or Y by the block size to put them next to each other. (Ex : Block number 3 will be placed at "3 * 16", or "3 * the size of a block")

int actualOffsetY = (y * blockSize) - (worldOffset * blockSize);

This time, to have the Y value with the offset, we need the Y position of the block and subtract the offset, still multiplied by the block size. It will bring the world down. We have to subtract to keep the coordinates system which is 0,0 = Top Left, like before. 


 Now. Let's check if in this loop, the Y position, with the offset is the same as the noise value. If it is, we can draw a grass block at the actual X and Y position like before : 


If you test your project, this is what you will see : 

And this is without the offset at the Y position :

The blocks before 0 aren't rendered, but the noise requires them to go above. That's where we need the offset. With the offset, we can have air blocks replaceable by real blocks above the grass instead of null blocks and errors. 


There is one last thing to do. Now we check if we are under the grass (Y with offset > than noise value, because we draw from up to down). If we are, we add a Stone block  : 


 Test your project once again and this is what you should see. The final noise system added : 

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @willfre! You have completed the following achievement on Steemit and have been rewarded with new badge(s) :

You published 4 posts in one day

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

You can upvote this notification to help all Steemit users. Learn why here!

Congratulations @willfre! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

You can upvote this notification to help all Steem users. Learn how here!