Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: Help With Diamond Square Terrain

  1. #1
    Junior Member
    Join Date
    Apr 2013
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Help With Diamond Square Terrain

    This code may be difficult to understand but basically I'm just trying to do the diamond square algorithm to make some terrain for a tile based game. I never found an example of this for a tiled game so I painstakingly converted someones midpoint displacement, that was for values between 1.0 & 0.0, to all positive numbers and whole number. I also fixed it for diamond square but im not sure if im doing that right. The 4 points of the diamond are actually 3 but i added the midpoint twice cause I didn't want to wrap. I feel like its not doing all the steps properly and in the pixel mode that i have as default atm shows diamond and square artifacts and even can be seen sometimes from the more zoomed in version too. One thing anyone would notice if they are familiar would be the fact a don't have a starting noise value and having it decrease after each completion (I am having trouble in this area too). For each step it is adding plus or minus 1. At the way bottom of the code is the keyboard handler and it set noise to 4 for now, clears the array, and makes new corner values after pressing spacebar. If someone can see if I did the diamond square wrong and have any tips for generating these numbers for a tile based game that would be awesome. The decimal places were making it difficult for me but I might go back and use em again but just times the height value by 10 or 100 to bump it up to something I may find more usable.

    package bttg;
     
    import java.awt.*;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.applet.*;
     
     
     
    @SuppressWarnings("serial")
    public class BTTG extends Applet implements KeyListener, MouseListener, FocusListener{
    		short i = 0;
    		int worldSize = 499; //99       <-------------------
    		int[][] map = new int[worldSize+1][worldSize+1];	
    		boolean focussed = false;
    		short rand;
    		double noise = 0;
     
     
    	public void init()
    	{
    		addKeyListener(this);
     
    	}
     
     
     
     
    	public boolean squareStep(int x, int y, int x1, int y1) //Diamond and Square Steps
    	{
     
    		if(x1-x<2 && y1-y<2) return false;
    		int sideMidX = (x+x1)/2;
    		int sideMidY = (y+y1)/2;
     
     
    		rand = (byte) (Math.random()*noise - (noise/2));  // These values are locked at the moment      random()*4 - (4/2); .... creates -1 to 1. 2 -1 wasn't working;  Try doing 6 - (6/2) for more bumpy terrain
    		if(map[sideMidX][sideMidY] == 0) map[sideMidX][sideMidY] = Math.abs((map[x][y] + map[x][y1] + map[x1][y] + map[x1][y1])/4 + (int)rand);  // Diamond
     
     
    		rand = (byte) (Math.random()*noise - (noise/2));
    		if(map[x][sideMidY] == 0)  map[x][sideMidY] = Math.abs((map[x][y1] + map[x][y] + map[sideMidX][sideMidY] + (map[sideMidX][sideMidY])+rand)/4) + (int) rand);  // Left side Squares or other way around\/\/\/ 
    // Having these at + 0 noise make really flat terrain which isnt bad  either
     
     
    		rand = (byte) (Math.random()*noise - (noise/2));
    		if(map[sideMidX][y] == 0)  map[sideMidX][y] = Math.abs((map[x1][y] + map[x][y] + map[sideMidX][sideMidY] + (map[sideMidX][sideMidY])+rand)/4) + (int) rand; // Top Side
     
     
    		rand = (byte) (Math.random()*noise - (noise/2));
    		if(map[sideMidX][y1] == 0)  map[sideMidX][y1] = Math.abs((map[x][y1] + map[x1][y1] + map[sideMidX][sideMidY] + (map[sideMidX][sideMidY])+rand)/4) + (int) rand; // Right Side
     
    		rand = (byte) (Math.random()*noise - (noise/2));
    		if(map[x1][sideMidY] == 0)  map[x1][sideMidY] = Math.abs((map[x1][y] + map[x1][y1] + map[sideMidX][sideMidY] + (map[sideMidX][sideMidY])+rand)/4) + (int) rand; 
     
     
    		squareStep(x,y,sideMidX,sideMidY);	
    		squareStep(sideMidX,y,x1,sideMidY);
    		squareStep(x,sideMidY,sideMidX,y1);
    		squareStep(sideMidX,sideMidY,x1,y1);
     
     
    	    return true;
    	}
     
     
     
     
    	public void paint(Graphics g)
    	{
     
     
    	int x=0;
    	int y=0;
     
    	g.setColor(Color.BLACK);
    	g.fillRect(0,0,1920,1080);
    	Font mapFont = new Font ("Monospaced", Font.BOLD, 8); // Not used this is to check the numbers below change to 12 if you want to see values
    	g.setFont(mapFont);
    	int xMap = 0;
    	int yMap = 0; // for numbers change this to 15
     
     
    	while(y<worldSize+1)
    	{   
    		Color bum = new Color(map[x][y], map[x][y],map[x][y]); // makes white shaded array values(times each one by 5 if displaying array values)
    		g.setColor(bum); // sets that color
    		g.fillRect(xMap, yMap,1,1);   //change this g.draw("" + map[x][y] ,xMap, yMap); to change from pixels to numbers (dont forget to change the others too and also change mapSize to 99 at the top
    		xMap += 1; // for numbers change this to 15
    		x++;
     
    		if(x == worldSize+1) 
    		{		
    			x=0;
    			y++;
    			xMap =0;
    			yMap += 1; // for numbers change this to 15
    		}
    		}
    	}
     
    	public void keyPressed(KeyEvent evt) 
    	{
    		int key = evt.getKeyCode(); 
     
    		if (key == KeyEvent.VK_SPACE)        //Space makes a new map
    		{
    			int x = 0,y = 0;
    			noise = 4;
    			while(y<worldSize+1)
    			{   
    				map[x][y] = 0;
    				x++;
     
    				if(x == worldSize+1)
    				{		
    					x=0;
    					y++;
    				}
     
    			}
     
    			rand = (short) ((Math.random()*(worldSize/2)));  // \/\/\/\/ These generate the starting corners
    			map[0][0] = rand;
    			rand = (short) ((Math.random()*(worldSize/2))); 
    			map[worldSize][0] = rand;
    			rand = (short) ((Math.random()*(worldSize/2)));
    			map[0][worldSize] = rand;
    			rand = (short) ((Math.random()*(worldSize/2)));
    			map[worldSize][worldSize] = rand;
     
    			 // rand = (short) ((Math.random()*(worldSize/2)));  // Take comments of to also place one midpoint seed
    			// map[worldSize/2][worldSize/2] = rand;
     
     
    			squareStep(0,0,worldSize,worldSize);
    			repaint();
    		}
    	}
     
    	public void keyReleased(KeyEvent evt) { }
    	public void keyTyped(KeyEvent evt) { char ch = evt.getKeyChar();}
    	public void mousePressed(MouseEvent evt) {requestFocus(); System.out.println("Mouse Works");}        
    	public void focusLost(FocusEvent evt) {focussed = false;}
    	public void focusGained(FocusEvent evt) {focussed = true; System.out.println("We Have Focus");}
    	public void mouseEntered(MouseEvent evt) { }  
    	public void mouseExited(MouseEvent evt) { }  
    	public void mouseReleased(MouseEvent evt) { } 
    	public void mouseClicked(MouseEvent evt) { }
     
     
    }
    Last edited by hobbles; May 5th, 2013 at 09:23 PM. Reason: Fixed the negative numbers I was still getting after fixing my Math.abs placement


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    18,560
    Thanks
    45
    Thanked 1,954 Times in 1,928 Posts

    Default Re: Help With Diamond Square Terrain

    The formulas need work. They keep generating -1 values in the map array.
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Junior Member
    Join Date
    Apr 2013
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Help With Diamond Square Terrain

    I'm still having problems with the square/ diamond looking artifacts in the output. Is it because I'm not progressively making the noise value smaller? I've been trying to think of a way to do this with out making too high of peaks since I need this to fit in a 3d array if it gets to big it'll go out of bounds. Also I need the hills and mountains to ascend only one value at a time since this is a top down 2d game the player character will only ascend 1 z layer at a time.

    Quote Originally Posted by Norm View Post
    The formulas need work. They keep generating -1 values in the map array.
    Where is it doing this I haven't found it yet. I thought since I have Math.abs on the averaging calculations it wouldn't let the values be negative. I'm thinking it should just start generating another hill or valley if it got low enough to go past that. Then again its the first time trying a lot of this so I'm not sure if I'm using it correctly.

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    18,560
    Thanks
    45
    Thanked 1,954 Times in 1,928 Posts

    Default Re: Help With Diamond Square Terrain

    Where is it doing this I haven't found it yet
    I didn't debug the code to find where.
    Here's a print of the contents of map
    // System.out.println("map="+java.util.Arrays.deepToS tring(map)); //<<<<<<<<<<<<<
    // map=[[3, 3, 2, 4, 3, 4, 3, 3, 1, 1, 3], [1, 2, 2, 3, 4, 2, 4, 5, 3, 3, 2],
    //[3, 1, 2, 3, 3, 4, 5, 4, 3, 4, 4], [2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 3],
    //[2, 1, 2, 1, 1, 2, 2, 2, 1, 3, 3], [3, 1, 2, 2, 1, 3, 4, 4, 4, 3, 3],
    //[3, 2, 2, 1, 1, 3, 3, 3, 3, 1, 1], [1, 1, 2, 3, 3, 3, 4, 4, 3, 2, 3],
    //[2, 2, 1, 2, 3, 2, 2, 4, 2, 0, 2], [1, 1, 1, 2, 2, 1, 2, 2, 3, 2, 2],
    //[1, -1, 1, 3, 3, 3, 1, 3, 1, 3, 3]]
    // ^^
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Junior Member
    Join Date
    Apr 2013
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Help With Diamond Square Terrain

    Cool I didn't know you could do that with an array very useful. I'm looking into it now, thanks alot man.

    After using "System.out.println("map="+java.util.Arrays.deepTo String(map));" I found out exactly what I did wrong to still get negative numbers, I forgot to use abs after adding positive or negative one. Haha stupid mistake thanks for helping with that.

  6. #6
    Junior Member
    Join Date
    Apr 2013
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Help With Diamond Square Terrain

    What's the best way to do this for a tile based game while I need smoother hills and such. Would doing diamond square normally between 0 and 1 be good then converting the height over by multiplying it by 100 or more to make it a whole number to work. I ask cause adding or subtracting 1 for the noise seems like it produces undesirable results since I don't have the noise decreasing with each pass through. What do people usually do for tile games? Perlin noise seems cool and read you can use it to make new values as you go like in minecraft but it seems like it is way beyond my understanding right now. Man it feels like I keep doing the stuff thats just beyond my grasp with java. : /

Similar Threads

  1. Replies: 10
    Last Post: April 21st, 2013, 09:28 AM
  2. Diamond perimeter with loop
    By Lanto in forum Loops & Control Statements
    Replies: 5
    Last Post: August 9th, 2012, 12:02 PM
  3. diamond pattern and loop
    By Naif in forum Loops & Control Statements
    Replies: 4
    Last Post: October 31st, 2011, 10:51 PM
  4. Method to print a diamond
    By snowMac in forum Algorithms & Recursion
    Replies: 1
    Last Post: March 8th, 2011, 03:18 AM
  5. asterisk forming diamond
    By cutee_eyeh in forum What's Wrong With My Code?
    Replies: 6
    Last Post: October 13th, 2010, 08:53 PM