I am creating a Minecraft-like engine in XNA. What I want to do is create floating islands similar to the one shown in this video:
http://www.youtube.com/watch?v=gqHVOEPQK5g&feature=related
How would I replicate this using a world generator? Would I have to use some Perlin noise algorithm? I don't know how that would help me make land masses like that.
Here is the code for the perlin noise generator that I am using:
private double[,] noiseValues;
private float amplitude = 1; // Max amplitude of the function
private int frequency = 1; // Frequency of the function
///
/// Constructor
///
///
public PerlinNoise(int freq, float _amp)
{
Random rand = new Random(System.Environment.TickCount);
noiseValues = new double[freq, freq];
amplitude = _amp;
frequency = freq;
// Generate our noise values
for (int i = 0; i < freq; i++)
{
for (int k = 0; k < freq; k++)
{
noiseValues[i, k] = rand.NextDouble();
}
}
}
///
/// Get the interpolated point from the noise graph using cosine interpolation
///
///
public double getInterpolatedPoint(int _xa, int _xb, int _ya, int _yb, double x, double y)
{
double i1 = interpolate(
noiseValues[_xa % Frequency, _ya % frequency],
noiseValues[_xb % Frequency, _ya % frequency]
, x);
double i2 = interpolate(
noiseValues[_xa % Frequency, _yb % frequency],
noiseValues[_xb % Frequency, _yb % frequency]
, x);
return interpolate(i1, i2, y);
}
public static double[,] SumNoiseFunctions(int width, int height, List noiseFunctions)
{
double[,] summedValues = new double[width, height];
// Sum each of the noise functions
for (int i = 0; i < noiseFunctions.Count; i++)
{
double x_step = (float)width / (float)noiseFunctions[i].Frequency;
double y_step = (float)height / (float)noiseFunctions[i].Frequency;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int a = (int)(x / x_step);
int b = a + 1;
int c = (int)(y / y_step);
int d = c + 1;
double intpl_val = noiseFunctions[i].getInterpolatedPoint(a, b, c, d, (x / x_step) - a, (y / y_step) - c);
summedValues[x, y] += intpl_val * noiseFunctions[i].Amplitude;
}
}
}
return summedValues;
}
///
/// Get the interpolated point from the noise graph using cosine interpolation
///
///
private double interpolate(double a, double b, double x)
{
double ft = x * Math.PI;
double f = (1 - Math.Cos(ft)) * .5;
// Returns a Y value between 0 and 1
return a * (1 - f) + b * f;
}
public float Amplitude { get { return amplitude; } }
public int Frequency { get { return frequency; } }
But the thing is the author of the code uses the following to generate noise, and I don't understand it in the least.
private Block[, ,] GenerateLandmass()
{
Block[, ,] blocks = new Block[300, 400, 300];
List perlins = new List();
perlins.Add(new PerlinNoise(36, 29));
perlins.Add(new PerlinNoise(4, 33));
double[,] noisemap = PerlinNoise.SumNoiseFunctions(300, 300, perlins);
int centrey = 400 / 2;
for (short x = 0; x < blocks.GetLength(0); x++)
{
for (short y = 0; y < blocks.GetLength(1); y++)
{
for (short z = 0; z < blocks.GetLength(2); z++)
{
blocks[x, y, z] = new Block(BlockType.none);
}
}
}
for (short x = 0; x < blocks.GetLength(0); x++)
{
for (short z = 0; z < blocks.GetLength(2); z++)
{
blocks[x, centrey - (int)noisemap[x, z], z].BlockType = BlockType.stone;
}
}
//blocks = GrowLandmass(blocks);
return blocks;
}
And here is the site I am using: http://lotsacode.wordpress.com/2010/02/24/perlin-noise-in-c/.
And I am trying to implement perlin noise in the way specified by Martin Sojka.
Ok, so this is what I have got so far:
Answer
For the base land, make two 2D continuous noise fields (Perlin, Simplex, Wavelet, a combination thereof - whatever works for you), one with mostly low frequency. low amplitude parts for the upper limit of the land, the other with both high frequency, high amplitude parts and low frequency, high amplitude for the lower limit of the land. Where the lower limit is above higher limit, don't include any land voxels (or whatever your game will be using to represent the terrain). The end result looks roughly like this ...
No comments:
Post a Comment