1
\$\begingroup\$

Not able to implement Perlin Noise for 1D Random Terrain Generation. I've tried everywhere and I cannot find anything useful, sure I sort of understand Perlin Noise but everytime I try it nothing works. I'm using LibGDX in Java if that helps, thanks.

Here is the code for P.N.

static float Noise(int x) {
    x = (x << 13) ^ x;
    return (float) (1.0 - ((x * (x * x * 15731 + 789221) + 1376312589) & Integer.MAX_VALUE) / 1073741824f);

}

public static float PerlinNoise1D(float x, float persistence, int octaves) {
    float total = 0;
    float p = persistence;
    int n = octaves - 1;

    for (int i = 0; i <= n; i++) {

        float frequency = (float) Math.pow(2, i);
        double amplitude = Math.pow(p, i);
        total += InterpolatedNoise(x * frequency) * amplitude;
    }

    return (int) total;

}

private static float InterpolatedNoise(float x) {
    int integer_X = (int) x;
    float fractional_X = x - integer_X;

    float v1 = SmoothNoise1D(integer_X);
    float v2 = SmoothNoise1D(integer_X + 1);

    return CosineInterpolate(v1, v2, fractional_X);

}

public static float CosineInterpolate(float a, float b, float x) {
    float ft = (float) (x * Math.PI);
    float f = (float) ((1 - Math.cos(ft)) * 0.5);

    return a * (1 - f) + b * f;
}

public static float SmoothNoise1D(int x) {
    return Noise(x) / 2 + Noise(x - 1) / 4 + Noise(x + 1) / 4;
}

and here is the code for the for loop used to render the tiles (assuming my tiles are 32px x 32px)

for (int i = 0; i < Gdx.graphics.getWidth(); i++) {
    float y = PerlinNoise1D(i, 5f, 3);
    for (int j = (int) (y); j < Gdx.graphics.getHeight(); j++) {
        hudBatch.begin();
        hudBatch.draw(hp, i, j);
        hudBatch.end();
        j+=31;
    }
    i+=31;
}

P.S I'm sort of trying to create a terraria-like game.

\$\endgroup\$
  • \$\begingroup\$ Are you trying to use perlin/simplex noise as a heightmap? \$\endgroup\$ – Quasiperfect Aug 1 '15 at 2:13
  • \$\begingroup\$ Yes, just to generate random hills with a seed. \$\endgroup\$ – Seeocon Aug 1 '15 at 12:36
1
\$\begingroup\$

I can't comment yet, but it's probably the i++ in the first line of:

for (int i = 0; i < Gdx.graphics.getWidth(); i++) {
    float y = PerlinNoise1D(i, 5f, 3);
    //other stuff
}

Since gradient noise is smooth at small intervals and abrupt at big intervals try and scale the value. Something like:

float y = PerlinNoise1D(i * 0.1, 5f, 3);
\$\endgroup\$
  • \$\begingroup\$ I swear I've tried that, awesome it worked... Now I just need to replace little 1x1 pixels with tiles, any idea on how to go about that? Again I need the tiles to be destructible sort of like a sandbox game. Here's the result of the change, before the hills were more spiky. here's a picture of it \$\endgroup\$ – Seeocon Aug 2 '15 at 1:18
  • \$\begingroup\$ @hzyy You're drawing pixel-per-pixel?? I recommend to at least learn how to draw sprites/textures. Imagine a square with a picture on top. They could be your tiles & I'm quite sure it's faster than per pixel. \$\endgroup\$ – Jader J Rivera Aug 2 '15 at 3:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.