Results 1 to 1 of 1
Thread: Java DiamondSquare Terrain
 03102014, 11:31 PM #1Member
 Join Date
 Mar 2013
 Location
 USA
 Posts
 25
 Rep Power
 0
Java DiamondSquare Terrain
Recently I've been experimenting with 2D terrain generation, mostly sideview terrarialike terrain. I settled on the Diamond Square algorithm and I almost got the heights working but I'm pretty sure I'm applying it wrong. I'm trying to generate the values and then apply the heights to the Y of blocks. I'll post my code below and let me explain what the different values are.
Here's where I apply the values from the diamondsquare:
Java Code:public static Chunk generateChunk() { Block[][] blocks = new Block[Chunk.CHUNK_WIDTH][Chunk.CHUNK_HEIGHT]; // CHUNK_WIDTH and CHUNK_HEIGHT are 9 Chunk chunk = new Chunk(blocks); // Chunk just stores an array of blocks, like the one above double[][] noise = DiamondSquare.diamondSquare(); for (int x = 0; x < blocks.length; x++) { for (int y = 0; y < blocks[0].length; y++) { blocks[x][y] = new Block(BlockType.DIRT, x * Block.BLOCK_WIDTH, y * Block.BLOCK_HEIGHT); // BLOCK_WIDTH and BLOCK_HEIGHT are 32, BlockType just stores textures } } for (int x = 0; x < noise.length; x++) { for (int y = 0; y < noise[0].length; y++) { int height = (int) (Math.abs(noise[x][y]) / Block.BLOCK_HEIGHT); // I don't want negative values and I was trying to divide the diamondsquare value so each block is 32 apart System.out.println(height); blocks[x][y].setY(height); // Setting the blocks y value here } } return chunk; }
Java Code:import java.util.Random; public class DiamondSquare { public static double[][] diamondSquare() { // size of grid to generate, note this must be a // value 2^n+1 final int DATA_SIZE = 9; // an initial seed value for the corners of the data final double SEED = 900.0; double[][] data = new double[DATA_SIZE][DATA_SIZE]; // seed the data data[0][0] = data[0][DATA_SIZE  1] = data[DATA_SIZE  1][0] = data[DATA_SIZE  1][DATA_SIZE  1] = SEED; double h = 500.0;// the range (h > +h) for the average offset Random r = new Random();// for the new value in range of h // side length is distance of a single square side // or distance of diagonal in diamond for (int sideLength = DATA_SIZE  1; // side length must be >= 2 so we always have // a new value (if its 1 we overwrite existing values // on the last iteration) sideLength >= 2; // each iteration we are looking at smaller squares // diamonds, and we decrease the variation of the offset sideLength /= 2, h /= 2.0) { // half the length of the side of a square // or distance from diamond center to one corner // (just to make calcs below a little clearer) int halfSide = sideLength / 2; // generate the new square values for (int x = 0; x < DATA_SIZE  1; x += sideLength) { for (int y = 0; y < DATA_SIZE  1; y += sideLength) { // x, y is upper left corner of square // calculate average of existing corners double avg = data[x][y] + // top left data[x + sideLength][y] + // top right data[x][y + sideLength] + // lower left data[x + sideLength][y + sideLength];// lower right avg /= 4.0; // center is average plus random offset data[x + halfSide][y + halfSide] = // We calculate random value in range of 2h // and then subtract h so the end value is // in the range (h, +h) avg + (r.nextDouble() * 2 * h)  h; } } // generate the diamond values // since the diamonds are staggered we only move x // by half side // NOTE: if the data shouldn't wrap then x < DATA_SIZE // to generate the far edge values for (int x = 0; x < DATA_SIZE  1; x += halfSide) { // and y is x offset by half a side, but moved by // the full side length // NOTE: if the data shouldn't wrap then y < DATA_SIZE // to generate the far edge values for (int y = (x + halfSide) % sideLength; y < DATA_SIZE  1; y += sideLength) { // x, y is center of diamond // note we must use mod and add DATA_SIZE for subtraction // so that we can wrap around the array to find the corners double avg = data[(xhalfSide+DATA_SIZE1)%(DATA_SIZE1)][y] + //left of center data[(x+halfSide)%(DATA_SIZE1)][y] + //right of center data[x][(y+halfSide)%(DATA_SIZE1)] + //below center data[x][(yhalfSide+DATA_SIZE1)%(DATA_SIZE1)]; //above center avg /= 4.0; // new value = average plus random offset // We calculate random value in range of 2h // and then subtract h so the end value is // in the range (h, +h) avg = avg + (r.nextDouble() * 2 * h)  h; // update value for center of diamond data[x][y] = avg; // wrap values on the edges, remove // this and adjust loop condition above // for nonwrapping values. if (x == 0) data[DATA_SIZE  1][y] = avg; if (y == 0) data[x][DATA_SIZE  1] = avg; } } } // print out the data /*for (double[] row : data) { for (double d : row) { System.out.printf("%8.3f ", d); } System.out.println(); }*/ /*for (int x = 0; x < data.length; x++) { for (int y = 0; y < data[0].length; y++) { System.out.println("Double: " + data[x][y]); System.out.println("Int: " + (int) data[x][y]); } }*/ return data; } }
Here's a screenshot of what happens: imgur: the simple image sharer which works, especially with the holes because I can fill them with ores/caves, but do you see how they're clumped together in squares? I want each block to be separated. Plus I don't think I know how to fill the holes with ores/caves, any ideas?
Similar Threads

Help Wanted! infinite terrain
By DRAGONMASTER412 in forum Forum LobbyReplies: 18Last Post: 03052014, 11:04 PM 
Java Random Terrain
By exonaut in forum Advanced JavaReplies: 2Last Post: 12112013, 06:48 PM 
Diamond in java
By gareth in forum New To JavaReplies: 0Last Post: 11172011, 02:27 PM 
What is the standard way of making 2D terrain?
By TacoManStan in forum New To JavaReplies: 7Last Post: 09152011, 12:57 PM 
3D Terrain on Sphere?
By quddusaliquddus in forum Advanced JavaReplies: 1Last Post: 06222009, 11:50 PM
Bookmarks