dcollis
asked on
2d tile based terrain generation
I'm looking for some examples / algorithms to automatically allow me to create an array of numbers that represent a 2d terrain i.e.
11112111
11122221
11223221
11223221
11122221
etc - for a larger grid - where the numbers represent different land types i.e. 1 for water, 2 for land, 3 for rock/impassable land...
A purely random approach would not be good enough as it would leave rocks in the middle of water and random patches of water here and there.
Any ideas anyone?
cheers,
dc.
11112111
11122221
11223221
11223221
11122221
etc - for a larger grid - where the numbers represent different land types i.e. 1 for water, 2 for land, 3 for rock/impassable land...
A purely random approach would not be good enough as it would leave rocks in the middle of water and random patches of water here and there.
Any ideas anyone?
cheers,
dc.
Here's something to play with. It starts with everything set to water, then builds up random rectangular islands.
import java.util.*;
public class Terrain
{
private Random random = new Random();
private int[][] terrain;
private void createIsland()
{
int centerX = random.nextInt(terrain.len gth);
int centerY = random.nextInt(terrain[0]. length);
terrain[centerX][centerY] = 2;
int verticalStart = centerY - (random.nextInt(3) + 2);
int horizontalStart = centerX - (random.nextInt(3) + 2);
int verticalStop = centerY + (random.nextInt(3) + 2);
int horizontalStop = centerX + (random.nextInt(3) + 2);
verticalStart = Math.max(0, verticalStart);
horizontalStart = Math.max(0, horizontalStart);
verticalStop = Math.min(terrain[0].length , verticalStop);
horizontalStop = Math.min(terrain.length, horizontalStop);
for (int x = horizontalStart; x < horizontalStop; x++)
{
for (int y = verticalStart; y < verticalStop; y++)
{
if ((x > horizontalStart) &&
(x < (horizontalStop - 1)) &&
(y > verticalStart) &&
(y < (verticalStop - 1)))
{
terrain[x][y] = 3;
}
else
{
terrain[x][y] = 2;
}
}
}
}
private void init()
{
terrain = new int[40][15];
// Fill with water
for (int x = 0; x < terrain.length; x++)
{
for (int y = 0; y < terrain[0].length; y++)
{
terrain[x][y] = 1;
}
}
// Create islands
for (int i = 0; i < 5; i++)
{
createIsland();
}
}
private void display()
{
System.out.println("Terrai n\n------- ");
for (int x = 0; x < terrain[0].length; x++)
{
for (int y = 0; y < terrain.length; y++)
{
System.out.print(terrain[y ][x]);
}
System.out.println();
}
}
public static void main(String args[])
{
Terrain t = new Terrain();
t.init();
t.display();
}
}
import java.util.*;
public class Terrain
{
private Random random = new Random();
private int[][] terrain;
private void createIsland()
{
int centerX = random.nextInt(terrain.len
int centerY = random.nextInt(terrain[0].
terrain[centerX][centerY] = 2;
int verticalStart = centerY - (random.nextInt(3) + 2);
int horizontalStart = centerX - (random.nextInt(3) + 2);
int verticalStop = centerY + (random.nextInt(3) + 2);
int horizontalStop = centerX + (random.nextInt(3) + 2);
verticalStart = Math.max(0, verticalStart);
horizontalStart = Math.max(0, horizontalStart);
verticalStop = Math.min(terrain[0].length
horizontalStop = Math.min(terrain.length, horizontalStop);
for (int x = horizontalStart; x < horizontalStop; x++)
{
for (int y = verticalStart; y < verticalStop; y++)
{
if ((x > horizontalStart) &&
(x < (horizontalStop - 1)) &&
(y > verticalStart) &&
(y < (verticalStop - 1)))
{
terrain[x][y] = 3;
}
else
{
terrain[x][y] = 2;
}
}
}
}
private void init()
{
terrain = new int[40][15];
// Fill with water
for (int x = 0; x < terrain.length; x++)
{
for (int y = 0; y < terrain[0].length; y++)
{
terrain[x][y] = 1;
}
}
// Create islands
for (int i = 0; i < 5; i++)
{
createIsland();
}
}
private void display()
{
System.out.println("Terrai
for (int x = 0; x < terrain[0].length; x++)
{
for (int y = 0; y < terrain.length; y++)
{
System.out.print(terrain[y
}
System.out.println();
}
}
public static void main(String args[])
{
Terrain t = new Terrain();
t.init();
t.display();
}
}
ASKER
I like this solution - its nice and quick and (when i play about with the variables a bit) creates some nice maps (I need all land connected to start with, so i changed it so that land would cover the area first and water would appear.
I will however, leave this question open a bit longer if you don't mind, to see if anyone else comes up with some other ideas
Thanks for the help so far,
dc.
I will however, leave this question open a bit longer if you don't mind, to see if anyone else comes up with some other ideas
Thanks for the help so far,
dc.
The 'philosophical' answer to your question ( and actually the same as jimmack is saying in practical terms :-)) is that you should be very carefull with your classification of 'area types'.
1 for water, 2 for land, 3 for rock/impassable land...
should not be such an 'off the top of your head' decided list.
For one thing it is hieraical:
1 for water, 2 for land, 2a for land with rock, 2b for land with forest, 1a for water with dangerous reefs, ...
by recognizing the hierachy there you are automatically led in the direction of jimmack's solution (I would not be surpriezed if that is just how he came to it).
For another thing we will want continuity, a checkerboard with black squares water and white squares land is neither believable nor usefull, so maybe we should introduce a landscape type 'beach' with the rule that beach squares must separate land and water. 1.5 for beach :-)
your choice of landscape types not just affect the evolution of your landscape, the landscape desired also to some extend suggest what landscape types you should chose.
regards JakobA
1 for water, 2 for land, 3 for rock/impassable land...
should not be such an 'off the top of your head' decided list.
For one thing it is hieraical:
1 for water, 2 for land, 2a for land with rock, 2b for land with forest, 1a for water with dangerous reefs, ...
by recognizing the hierachy there you are automatically led in the direction of jimmack's solution (I would not be surpriezed if that is just how he came to it).
For another thing we will want continuity, a checkerboard with black squares water and white squares land is neither believable nor usefull, so maybe we should introduce a landscape type 'beach' with the rule that beach squares must separate land and water. 1.5 for beach :-)
your choice of landscape types not just affect the evolution of your landscape, the landscape desired also to some extend suggest what landscape types you should chose.
regards JakobA
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Really sorry i left this question open so long. Totally forgot about it until i came to ask another question in this topic area today.
Sorry again,
dc.
Sorry again,
dc.
;-) It's OK. At least you didn't get a CleanupPing ;-)
1) Set all locations to water
2) Create island (repeatedly if necessary)
2.1) Pick a random location for the centre of an island
2.2) Create the land for the whole island (replacing 1s with 2s)
2.3) Within the island, create the impassable region (replacing 2s with 3s)
This way, you'll always have islands surrounded by water and the impassable areas will only appear on land. Also, it doesn't matter if the islands overlap. This would just create larger islands.
The key to this technique is to build up the landscape from bottom up (a bit like oil painting ;-))