Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Random Map Generation  (Read 9501 times)
0 Members and 1 Guest are viewing this topic.
Offline Pinguinpanic

Junior Member


Medals: 3



« Posted 2012-01-04 01:02:26 »

Hello there, I'm new here, and thought I'd share something isntead of only being here to ask annoying questions.

I'm working on some random map generation for a game I am working on, and I was thinking that some sharing of thoughs on map generation would be nice, since my stuff so far is far from perfect.

What I am doing at the moment, is rather simple, and would be best described in a snippet of code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
//Repeat for a set number of times
for(int i=0;i<laketimes;i++)
    {
      //Pick a point somewhere in the map
     pointX=genValue(WIDTH);
      pointY=genValue(HEIGHT);
      for(int x=0;x<WIDTH;x+=1)
      {
        for(int y=0;y<HEIGHT;y+=1)
        {
          //For every value, take the distance
         int t=distance(x,y,pointX,pointY);
          //And then add to the map's height, a number depending on Cos(Distance*90)
         value[x][y]+=(int)(100.0*Math.cos(t/10+90));
        }
      }  
    }

I also added in a bit of white noise over the whole thing, and afterwards I smooth it out, by for every x,y assigning the average of the surrounding values. I do this two times but I guess that is all down to flavor, here's a pic of my method:

As you can see, everything seems to be a bit circling arround the lakes.

So anyone have past experience with generating maps?
Offline SimonH
« Reply #1 - Posted 2012-01-04 01:50:56 »

If you use regular functions like cos then you're going to get regular results...
A simple solution would be to add multiple cos functions at different resolutions.Try;
1  
value[x][y]+=(int)(100.0*Math.cos(t/10+90)+50*Math.cos(t/5+45));
for example.

A more advanced solution would be Perlin Noise.

People make games and games make people
Offline theagentd
« Reply #2 - Posted 2012-01-04 02:07:08 »

As you can see, everything seems to be a bit circling arround the lakes.
You mean like IRL? >_> I think that map looks awesome...

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Roquen
« Reply #3 - Posted 2012-01-04 03:53:49 »

Quote
A more advanced solution would be Perlin Noise.

I wish Hugo would edit this page.  This is "value" noise and not Perlin.  The concepts are fine, the noise function is not.  There are various noise implementations in various thread here which can be searched for.
Offline SwampChicken
« Reply #4 - Posted 2012-01-04 04:18:25 »

Nice. How many tiles across is that?
Offline Shazer2

Junior Member


Medals: 3


Aspiring developer.


« Reply #5 - Posted 2012-01-04 07:15:09 »

This is very interesting and cool. Hopefully one day I can do stuff like this.

~Shazer2

"When you want to be successful as bad as you want to breathe, then you will be successful." - Eric Thomas
Offline Swattkidd7

Junior Member





« Reply #6 - Posted 2012-01-04 08:07:09 »

I see how you are storing the values into the 2D array of "values" but what exactly do you do with those values? How do you render the map?

Anyway, the map looks really nice, good work and thanks!
Offline princec

JGO Kernel


Medals: 343
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #7 - Posted 2012-01-04 11:31:58 »

I really like that map - it has a "real" look to it.

Cas Smiley

Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #8 - Posted 2012-01-04 12:17:13 »

If you use regular functions like cos then you're going to get regular results...
A simple solution would be to add multiple cos functions at different resolutions.Try;
1  
value[x][y]+=(int)(100.0*Math.cos(t/10+90)+50*Math.cos(t/5+45));
for example.

A more advanced solution would be Perlin Noise.
Thanks for that tip, I was actually aiming for Perlin noise, but my math skills are pretty meh, so I just left it at cos(blah), but that link is really helpfull. I got the idea of taking points and aplying a "formula" from the distance from this link: http://www.noisemachine.com/talk1/, it's from one of the guys who did 3d graphics for the Tron movie, apparently all of that stuff was just algorithms, no prefabs. It's quite an interesting read, if anyone's interested.

Nice. How many tiles across is that?
It's 200x200, I'm using a tilesize of 8x4, but the tiles I'm drawing are atcually 16x8 Tongue, so if you zoomed in, it would look awkard. Just doing it for testing sake, the real tiles are 64x32.

This is very interesting and cool. Hopefully one day I can do stuff like this.

~Shazer2
It's nothing very fancy, I just have a 2D array storing what tile to draw at a position, and one of my friends made me a nice tileset. What part of this looks difficult? I might be able to give you a pointer in the right direction.

I see how you are storing the values into the 2D array of "values" but what exactly do you do with those values? How do you render the map?

Anyway, the map looks really nice, good work and thanks!
I have a set of tiles stored in an array "tilesheet[]" of which 1 is Water, 2 is Sand, 3 is Grass, 4 is elevated Grass, 5 is more elevated grass and 6 is most elevated grass. To determine the tile for every tile I use the value[][] that I calculate with my mapgenerating algorithm, the script looks like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
  public int getTile(int x, int y)
  {
    int ret=value[x][y];
    if(ret<35) return 1;
    if(ret<45) return 2;
    if(ret<75) return 3;
    if(ret<90) return 4;
    if(ret<95) return 5;
    return 6;
}

I just fiddled with these numbers untill it looked nice, I'm not a very organized programmer, I ussually just mess arround untill it looks good/works.


Thanks for all the positive feedback (: does anyone have ideas on how you could create a method that also works with an expandable world? The weakness of my method is that, if you want the expand the world, the "seeds" that you used will all be really close, while the rest of the world is far away, resulting in simply circles arround your original part of the map:

The north quarter of the map was the original map in this image.
Offline roland
« Reply #9 - Posted 2012-01-04 12:31:04 »

You draw every tile, one at a time? and you just draw textured cubes?
like
for (int x = 0; x < numTilesX; x++)
{
   for (int z = 0; z < numTilesZ; z++)
   {
      //draw the highest(y value) block here and ignore the lower ones?
   }
}

Edit: this is 2d?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #10 - Posted 2012-01-04 12:43:24 »

You draw every tile, one at a time? and you just draw textured cubes?
like
for (int x = 0; x < numTilesX; x++)
{
   for (int z = 0; z < numTilesZ; z++)
   {
      //draw the highest(y value) block here and ignore the lower ones?
   }
}

Edit: this is 2d?
It's 2d, my tileset kind of has the height in it, like this:

Then I just draw them one by one, starting from the top to make sure the front ones are in front of the back ones.
Offline SimonH
« Reply #11 - Posted 2012-01-04 13:04:05 »

I was actually aiming for Perlin noise, but my math skills are pretty meh, so I just left it at cos(blah)
Forgot to say, you might find this useful.

People make games and games make people
Offline Mike

JGO Ninja


Medals: 71
Projects: 1
Exp: 5 years


Java guru wanabee


« Reply #12 - Posted 2012-01-04 13:36:37 »

The north quarter of the map was the original map in this image.

Right, here the circle look is very visible indeed and it looks less good. Other than that, nice looking rendering! Smiley

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Offline tackman

Senior Newbie





« Reply #13 - Posted 2012-01-04 13:40:59 »

The Cos function is a cyclic function, meaning - statistically - it will bear similar results over time. Maybe your circling behavior can be accounted to the use of the Cos function?

Try spicing it up, either by adding another Cos function with a different argument, or modifying the argument of the Cos function by a random multiplier. Not sure if these would work, but they are at least worth a try.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2012-01-04 19:44:16 »

The weakness of my method is that, if you want the expand the world, the "seeds" that you used will all be really close, while the rest of the world is far away, resulting in simply circles arround your original part of the map:
Then make the seeds not so close to eachother... spread them evenly across you larger world.

It would probably a good idea too to fade the influence of a 'seed' with distance.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #15 - Posted 2012-01-05 09:35:10 »

The weakness of my method is that, if you want the expand the world, the "seeds" that you used will all be really close, while the rest of the world is far away, resulting in simply circles arround your original part of the map:
Then make the seeds not so close to eachother... spread them evenly across you larger world.

It would probably a good idea too to fade the influence of a 'seed' with distance.
Problem is, if I add a piece of map, with a seed on it, it will have to have an effect on the previously generated map, unless I make it fade somehow at the edges. Maybe I could just choose my "seeds" somewhere outside of my current map I just realized, there's no reason for the calculation to require the seeds to be within the array, so I could try that and see how it looks.
Online Roquen
« Reply #16 - Posted 2012-01-05 10:53:46 »

What you're (in effect) attempting to do is fake noise, so unless you're having fun, just change to using some noise function.
Offline Damocles
« Reply #17 - Posted 2012-01-05 11:33:54 »

Here a simple mapgenerator, not fancy, but it will create the hightmap of some island type landscape





1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
import java.applet.Applet;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.Random;

/*
simple Island generator by Damocles
*/


public class MapGen extends Applet implements Runnable
{

   static int wide = 1000;
   static int high = 800;

   public void start()
   {
      new Thread(this).start();
   }

   public void run()
   {
      while (!this.isActive())
         Thread.yield();
     
      setSize(wide,high);
      Random ran = new Random();

      BufferedImage image = new BufferedImage(wide, high, BufferedImage.TYPE_INT_RGB);
     
      int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

      double[][] map = new double[wide][high];

     
      int iterator=1;
      int stepsize=wide/16;
      do
      {
      for (int y = stepsize; y <= high-stepsize*2; y+=stepsize)
      {
         for (int x = stepsize; x <= wide-stepsize*2; x+=stepsize)
         {
            //apply random offset (tweak this)
           int val=ran.nextInt(40+iterator*2)-20 - iterator*1;
           
            //initial features
           int valFirst=50+ran.nextInt(200);
           
            for (int yy = 0; yy < stepsize; yy++)
            {
               for (int xx = 0; xx < stepsize; xx++)
               {
                  if(iterator==1)    map[x+xx][y+yy] =valFirst;
                  else {
                     
                  //apply random value  
                 map[x+xx][y+yy] += val;
                 
                  //average out
                 map[x+xx][y+yy]=  
                     (map[x+xx][y+yy]*2 +
                     map[x+stepsize+xx][y+yy] +
                     map[x-stepsize+xx][y+yy] +
                     map[x+xx][y+yy+stepsize] +
                     map[x+xx][y+yy-stepsize] +
                     
                     map[x+stepsize+xx][y+yy+stepsize] +
                     map[x+stepsize+xx][y+yy-stepsize]+
                     map[x-stepsize+xx][y+yy+stepsize] +
                     map[x-stepsize+xx][y+yy-stepsize]
                     
                     ) / 10 ;
                  }
                  if(map[x+xx][y+yy]>255) map[x+xx][y+yy]=255;
                  if(map[x+xx][y+yy]<0) map[x+xx][y+yy]=0;
                 
               }
            }
           
           
         }
      }
     
      iterator++;
      stepsize/=2;
     
      } while(stepsize>0);
     
     
      //smoothing
     for(int passes=0;passes<10;passes++)
      {
         
     
      for (int y = 1; y < high-1; y++)
      {
         for (int x = 1; x < wide-1; x++)
         {
           
            map[x][y]=  
               (
               map[x][y]*2 +
               map[x+1][y] +
               map[x-1][y] +
               map[x][y+1] +
               map[x][y-1] +
               
               map[x+1][y+1] +
               map[x+1][y-1]+
               map[x-1][y+1] +
               map[x-1][y-1]
               
               ) / 10;
         }
      }
      }
     
     
     
      for (int i = 0; i < pixels.length; i++)
      {
         //make water
        pixels[i]=0x40A0FF;
         
         int mv= (int)map[i % wide][i / wide];
         int mvRB= (int)(map[i % wide][i / wide]*0.5);  //make Red and Blue darker
        if(mvRB>255) mvRB=255;
         
         if(mv>140)
            {
            pixels[i] = (mvRB << 16) | (mv <<8) | mvRB;
            if(mv<152)pixels[i] = 0xE0D090;  //beach
           }
         
      }

      while (isActive())
      {
         this.getGraphics().drawImage(image, 0, 0, null);
         Thread.yield();
      }
   }

   
}

Offline Damocles
« Reply #18 - Posted 2012-01-05 15:54:56 »

There are many parameters that can be tweaked.
Especially how much noise is applies for each step, and how much it should be smoothed.

Online Roquen
« Reply #19 - Posted 2012-01-05 16:02:38 »

This is basically value noise broken into a two step (and significantly more expensive) processes...why bother?  Just use an existing noise function rather than re-inventing the wheel.
Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #20 - Posted 2012-01-05 17:47:06 »

1  
2  
3  
4  
[quote author=Damocles link=topic=25442.msg219354#msg219354 date=1325759634]
/*
simple Island generator by Damocles
*/

[/quote]
That is basicly just "noise" applied to increasingly smaller segments? That's a pretty nifty idea as well. Looks good, that would be like 10 passes for an 1024x1024 field right? (2^10), +10 for smoothing would be about 20 passes. I think mine has about as many passes, but yours is probably better if you want to expand the map.

This is basically value noise broken into a two step (and significantly more expensive) processes...why bother?  Just use an existing noise function rather than re-inventing the wheel.
What you're (in effect) attempting to do is fake noise, so unless you're having fun, just change to using some noise function.
Sorry, but I'm still a beginning programmer, just finding out about all this stuff. Where do you guys aquire this knowledge? Is it something that builds up over time, or are there sites/books that are bundles with usefull information like this? I'm currently reading into the "Value Noise" you talked about, and I think that would be usefull for terrain generation.
Online Roquen
« Reply #21 - Posted 2012-01-05 17:53:50 »

IMHO: Value noise isn't of great interest.  You'd probably should use Perlin gradient noise.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #22 - Posted 2012-01-05 17:58:45 »

What you're (in effect) attempting to do is fake noise, so unless you're having fun, just change to using some noise function.
You have got to agree his terrain has a unique feel. Value noise and perlin noise typically look rather boring and unnatural, unless it's finetuned into oblivion.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Damocles
« Reply #23 - Posted 2012-01-05 18:10:00 »

In the end what counts is how the result looks like.
No need for academic discussions on that.

BTW: how can terraingeneration be inperformant, that not a realtime application, the performce does not
matter there. Be it 1 or 3 seconds at initial worldgeneration, noone cares.

Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #24 - Posted 2012-01-05 18:47:14 »

In the end what counts is how the result looks like.
No need for academic discussions on that.

BTW: how can terraingeneration be inperformant, that not a realtime application, the performce does not
matter there. Be it 1 or 3 seconds at initial worldgeneration, noone cares.
Well, I want to add new terrain in real time, but I guess if I'd for example add chuncks of like 32x32 at a time, that that should be still very doable in real time. So well yes, it doesn't matter at all haha Tongue. Sometimes I just have no idea where I'm going
Offline Damocles
« Reply #25 - Posted 2012-01-05 19:30:47 »

no was directed at Roquen's post.

Anyhow, there are many good tutorials online. And since your voxel-cube rendering looks good already, you should be able to
make a nice terrain in no time.

The circular terrain still looks good. Maybe you can leave it in to be applied at some parts of your world.


Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #26 - Posted 2012-01-05 19:57:40 »

no was directed at Roquen's post.

Anyhow, there are many good tutorials online. And since your voxel-cube rendering looks good already, you should be able to
make a nice terrain in no time.

The circular terrain still looks good. Maybe you can leave it in to be applied at some parts of your world.


I'm not drawing voxel-cubes or anything, it's just images. Here's an image of the world upclose, that was just a version of the game with smaller images:

Currently breaking my head on building a system to load tile variations from a file so that I can just change a text file for different graphics instead of code. It's ussually the basic stuff that gets me stuck, Java always mock me like that, with stuff like LOL YOU LOADED AN IMAGE, AND I CAN DISPLAY THE WIDTH OF THAT IMAGE FOR TESTING PURPOSE, BUT THERE'S NO WAY I AM GOING TO DRAW THAT ON SCREEN.

Sorry for the rambling, after I have the system done, I will get back to terrain generation, and I can share with you my silly ideas of treeplanting, and rockplacing on the map. That is, if anyone is interested.
Offline ra4king

JGO Kernel


Medals: 337
Projects: 2
Exp: 5 years


I'm the King!


« Reply #27 - Posted 2012-01-05 22:32:21 »

Oooh I'm interested! Keep sharing your silly ideas because I love them Smiley I've been quietly lurking this thread because random map generation has always amazed and baffled me Smiley

Offline Pinguinpanic

Junior Member


Medals: 3



« Reply #28 - Posted 2012-01-05 23:31:47 »

Hey, I'm back with some more not-really related stuff. But while making this I was thinking IT'S KIND OF BORING TO HAVE THE SAME GRASS TILE ALL THE TIME. So I said to my spritedrawing friend DO THOSE SPRITES AGAIN BUT NOW WITH FLOWERS AND LITTLE POOLS OF MUD. And he did (Thanks Cheesy ), so then I had to make some way to get the flowers in game, which COULD mean I would have to hardcore all the sprites and blah blah, but I thought that would not be very good for development of the game later on, so instead I create this sytem, where the only thing I have to do to get a tile ingame, with a couple of variations, is this:
[Code]tType[3]=new TileResource("Grass"); [/Code]
So you might be thinking, but how does it load all it's information? Well, I simply have a file grass.props, that has this text:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
Name=Grass
Height=0
Images=5
Image1=Grass.png
Image1Freq=800
Image2=Grasshole.png
Image2Freq=5
Image3=Grasshole2.png
Image3Freq=5
Image4=Grasshorseflower.png
Image4Freq=100
Image5=Grasshorseflower2.png
Image5Freq=100
So from that I just load the props, and images, this way instead of having to think and try how many percent of my grass I want all happy with flowers, I can just tell my graphic designing friend, to do that stuff.

Tl;dr: I am lazy and post stuff not related to Map Generation to a map generation thread, here's a pretty picture of my work:
Offline sproingie

JGO Kernel


Medals: 202



« Reply #29 - Posted 2012-01-05 23:33:38 »

Nice.  Just need a bit of texture splatting and you're all set.
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

E.R. Fleming (15 views)
2014-07-29 03:07:13

E.R. Fleming (4 views)
2014-07-29 03:06:25

pw (39 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21

Zero Volt (50 views)
2014-07-17 23:47:54

danieldean (42 views)
2014-07-17 23:41:23

MustardPeter (44 views)
2014-07-16 23:30:00
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!