Jump to content

  • Log In with Google      Sign In   
  • Create Account

TrickyLogic

Member Since 24 Sep 2011
Offline Last Active Apr 23 2013 10:38 AM

#5033341 A Dream of breaking in as a developer - Looking to build a team

Posted by TrickyLogic on 17 February 2013 - 05:35 AM

What are you going to bring to the table? You either need to be a valuable member yourself or fund the rest of the team. I'm just asking out of curiosity because you haven't shared any info about yourself.




#5015035 Island Generation -- Problem with Duplicates

Posted by TrickyLogic on 28 December 2012 - 04:27 AM

Thankyou very much for this! I like the randomness and I love the code but do you know if there is any way to make it less "holey". There are specks of water all over the terrain and what I am going for is more of a solid island surrounded by water

 

 

You're probably better off writing your own noise function if you want that amount of control. The problem is both with the perlin noise and the island mask. Some fixes that make it a bit better:

//Little program to generate test map with only 0 and 1 tile

#include <iostream>
#include <noise/noise.h>
#include "noiseutils.h"
#include <stdlib.h>
#include <string>
#include <sstream>

#define MAP_SIZE 512

using namespace std;
using namespace noise;

template <typename T> string tostring (T v) {
    ostringstream ss;
    ss << v;
    return ss.str();
}

void generate_island(int iseed) {
    module::Perlin myModule;

    myModule.SetSeed (iseed);
    utils::NoiseMap heightMap;
    utils::NoiseMapBuilderPlane heightMapBuilder;
    heightMapBuilder.SetSourceModule(myModule);
    heightMapBuilder.SetDestNoiseMap(heightMap);
    heightMapBuilder.SetDestSize(MAP_SIZE, MAP_SIZE);
    heightMapBuilder.SetBounds(2.0, 6.0, 1.0, 5.0);
    heightMapBuilder.Build();

    float islandMap[MAP_SIZE][MAP_SIZE];
    srand(iseed);

    for (int count = 0; count < 1; count++ ){
        //Initialize values for a new map
        for (int i = 0; i < MAP_SIZE; i++) {
            for (int j = 0; j < MAP_SIZE; j++) {
                islandMap[j][i] = 0;
            }
        }

        //Choose a random location, travel in random directions
        int x = 0, y = 0;
        int sx = 0, sy = 0;
        int size = MAP_SIZE / 2;
        int distance = 0;

        for (int i = 0; i < 1000000; i++) {
            int dx = x - sx;
            int dy = y - sy;
            distance = dx * dx + dy * dy;
            if((y > MAP_SIZE - 1) || y < 0 || (x > MAP_SIZE - 1) || x < 0 || distance > 5000) {
                x = rand() % size / 2 + rand() % size / 2 + MAP_SIZE / 2 - size / 2;
                y = rand() % size / 2 + rand() % size / 2 + MAP_SIZE / 2 - size / 2;
                sx = x;
                sy = y;
            }

            ++islandMap[x][y];

            switch(rand() % 4) {
                case 0:
                    ++x;
                    break;
                case 1:
                    --y;
                    break;
                case 2:
                    --x;
                    break;
                case 3:
                    ++y;
                    break;
                default:
                    break;
            }
        }

        //find max value for normalizing
        for (int i = 0; i < MAP_SIZE; i++) {
            for (int j = 0; j < MAP_SIZE; j++) {
                islandMap[i][j] = islandMap[i][j] * 2 - 1;
            }
        }

        int max = 0;
        int min = 0;
        for (int i = 0; i < MAP_SIZE; i++) {
            for (int j = 0; j < MAP_SIZE; j++) {
                if(max < islandMap[i][j]) {
                    max = islandMap[i][j];
                }

                if(min > islandMap[i][j]) {
                    min = islandMap[i][j];
                }
            }
        }

        //Multiply values of original by new maps generated
        for (int i = 0; i < MAP_SIZE; i++) {
            for (int j = 0; j < MAP_SIZE; j++) {
                float islandValue = (islandMap[i][j] - min) / (max - min);
                float mapValue = (heightMap.GetValue(i, j) + 1) / 2;
                float newValue = 2 * islandValue * mapValue - 1;
                heightMap.SetValue(i, j, newValue);
            }
        }
    }

    utils::RendererImage renderer;
    utils::Image image;
    renderer.SetSourceNoiseMap (heightMap);
    renderer.SetDestImage (image);
    renderer.ClearGradient ();
    renderer.AddGradientPoint (-1.0000, utils::Color (  0,   0, 255, 255)); // shallow
    renderer.AddGradientPoint (-0.9701, utils::Color (  0,   0, 255, 255)); // shallow
    renderer.AddGradientPoint (-0.9700, utils::Color (  0, 128, 255, 255)); // shore
    renderer.AddGradientPoint (-0.9690, utils::Color (  0, 128, 255, 255)); // shore
    renderer.AddGradientPoint (-0.9689, utils::Color (240, 240,  64, 255)); // sand
    renderer.AddGradientPoint (-0.9601, utils::Color (240, 240,  64, 255)); // sand
    renderer.AddGradientPoint (-0.9600, utils::Color ( 32, 160,   0, 255)); // grass
    renderer.AddGradientPoint (-0.4991, utils::Color ( 32, 160,   0, 255)); // grass
    renderer.AddGradientPoint (-0.4990, utils::Color ( 0, 0,   0, 255)); // pines
    renderer.AddGradientPoint (-0.4987, utils::Color ( 0, 0,   0, 255)); // pines
    renderer.AddGradientPoint (-0.3986, utils::Color (96, 63,   0, 255)); // dirt
    renderer.AddGradientPoint ( 0.0000, utils::Color (96, 63,   0, 255)); // dirt
    renderer.AddGradientPoint ( 0.0001, utils::Color (128, 128, 128, 255)); // rock
    renderer.AddGradientPoint ( 1.0000, utils::Color (128, 128, 128, 255)); // rock
    renderer.EnableLight ();
    renderer.SetLightContrast (3.0);
    renderer.SetLightBrightness (2.0);
    renderer.Render ();

    utils::WriterBMP writer;
    writer.SetSourceImage (image);
    writer.SetDestFilename ("tutorial" + tostring(iseed) + ".bmp");
    writer.WriteDestFile ();
}

int main() {
    for(int i=0; i<10; ++i){
        generate_island(i);
    }
    return 0;
}

The island mask consists of many random walks added together. The random walks scale poorly with size of the map (change the MAP_SIZE to see for yourself) because they tend to diverge very quickly. With the above code I've applied two methods two remedy this a bit:

  1. Terminate any random walk if they get beyond a certain distance away from their origin.
  2. Make the starting point of any random walk more likely to be in the middle with a triangular distribution and within a smaller region (controlled with the 'size' variable).

Play a bit with the numbers to see if you can improve the results.

 

If you want to try something else try this instead: http://en.wikipedia.org/wiki/Diamond-square_algorithm If you set the first N levels yourself instead of randomly generating them you get much more control over the final output.

Attached Thumbnails

  • tutorial0.png
  • tutorial1.png



#5014943 Island Generation -- Problem with Duplicates

Posted by TrickyLogic on 27 December 2012 - 07:41 PM

The algorithm used looks like the same from: http://breinygames.blogspot.nl/2012/06/generating-terrain-using-perlin-noise.html

 

Just playing around a little (I did change some code so I could more easily read it), here is what I came up with:

//Little program to generate test map with only 0 and 1 tile

#include <iostream>
#include <noise/noise.h>
#include "noiseutils.h"
#include <stdlib.h>
#include <string>
#include <sstream>

using namespace std;
using namespace noise;

template <typename T> string tostring (T v) {
    ostringstream ss;
    ss << v;
    return ss.str();
}

void generate_island(int iseed) {
    module::Perlin myModule;

    myModule.SetSeed (iseed);
    utils::NoiseMap heightMap;
    utils::NoiseMapBuilderPlane heightMapBuilder;
    heightMapBuilder.SetSourceModule(myModule);
    heightMapBuilder.SetDestNoiseMap(heightMap);
    heightMapBuilder.SetDestSize(512, 512);
    heightMapBuilder.SetBounds(2.0, 6.0, 1.0, 5.0);
    heightMapBuilder.Build();

    float islandMap[512][512];
    srand(iseed);

    for (int count = 0; count < 1; count++ ){
        //Initialize values for a new map
        for (int i = 0; i < 512; i++) {
            for (int j = 0; j < 512; j++) {
                islandMap[j][i] = 0;
            }
        }

        //Choose a random location, travel in random directions
        int x = 0, y = 0;
        float previous = 0;

        for (int i = 0; i < 1000000; i++) {
            if(y == 511 || y == 0 || x == 511 || x == 0) {
                x = rand() % 512;
                y = rand() % 512;
            }   

            if(previous >= islandMap[x][y]) {
                islandMap[x][y] += 1;
            }

            previous = islandMap[x][y];

            switch(rand() % 4) {
                case 0:
                    x -= 1;
                    break;
                case 1:
                    y -= 1;
                    break;
                case 2:
                    x += 1;
                    break;
                case 3:
                    y += 1;
                    break;
                default:
                    break;
            }
        }

        //find max value for normalizing
        for (int i = 0; i < 512; i++) {
            for (int j = 0; j < 512; j++) {
                islandMap[i][j] = islandMap[i][j] * 2 - 1;
            }
        }

        int max = 0;
        int min = 0;
        for (int i = 0; i < 512; i++) {
            for (int j = 0; j < 512; j++) {
                if(max < islandMap[i][j]) {
                    max = islandMap[i][j];
                }

                if(min > islandMap[i][j]) {
                    min = islandMap[i][j];
                }
            }
        }

        //Multiply values of original by new maps generated
        for (int i = 0; i < 512; i++) {
            for (int j = 0; j < 512; j++) {
                float islandValue = (islandMap[i][j] - min) / (max - min);
                float mapValue = (heightMap.GetValue(i, j) + 1) / 2;
                float newValue = 2 * islandValue * mapValue - 1;
                heightMap.SetValue(i, j, newValue);
            }
        }
    }

    utils::RendererImage renderer;
    utils::Image image;
    renderer.SetSourceNoiseMap (heightMap);
    renderer.SetDestImage (image);
    renderer.ClearGradient ();
    renderer.AddGradientPoint (-1.0000, utils::Color (  0,   0, 255, 255)); // shallow
    renderer.AddGradientPoint (-0.9701, utils::Color (  0,   0, 255, 255)); // shallow
    renderer.AddGradientPoint (-0.9700, utils::Color (  0, 128, 255, 255)); // shore
    renderer.AddGradientPoint (-0.9690, utils::Color (  0, 128, 255, 255)); // shore
    renderer.AddGradientPoint (-0.9689, utils::Color (240, 240,  64, 255)); // sand
    renderer.AddGradientPoint (-0.9601, utils::Color (240, 240,  64, 255)); // sand
    renderer.AddGradientPoint (-0.9600, utils::Color ( 32, 160,   0, 255)); // grass
    renderer.AddGradientPoint (-0.4991, utils::Color ( 32, 160,   0, 255)); // grass
    renderer.AddGradientPoint (-0.4990, utils::Color ( 0, 0,   0, 255)); // pines
    renderer.AddGradientPoint (-0.4987, utils::Color ( 0, 0,   0, 255)); // pines
    renderer.AddGradientPoint (-0.3986, utils::Color (96, 63,   0, 255)); // dirt
    renderer.AddGradientPoint ( 0.0000, utils::Color (96, 63,   0, 255)); // dirt
    renderer.AddGradientPoint ( 0.0001, utils::Color (128, 128, 128, 255)); // rock
    renderer.AddGradientPoint ( 1.0000, utils::Color (128, 128, 128, 255)); // rock
    renderer.EnableLight ();
    renderer.SetLightContrast (3.0);
    renderer.SetLightBrightness (2.0);
    renderer.Render ();

    utils::WriterBMP writer;
    writer.SetSourceImage (image);
    writer.SetDestFilename ("tutorial" + tostring(iseed) + ".bmp");
    writer.WriteDestFile ();
}

int main() {
    for(int i=0; i<10; ++i){
        generate_island(i);
    }
    return 0;
}

 

 

 

Attached Thumbnails

  • tutorial0.png
  • tutorial1.png



#4982986 How to get the number of solid tiles between two points?

Posted by TrickyLogic on 23 September 2012 - 11:55 AM

Now, as others have said, if your really just wanting 'the number of solid tiles between two points' and your counting the tiles in red in the photo, then it is just the greater of the absolute of the difference in Y or X. (As defined by the outer loop in the algorithm.)


This algorithm wouldn't account for any missing tiles. Although it would speed it up greatly. Perhaps a switch can be implemented for people using slower computers.


#4982910 How to get the number of solid tiles between two points?

Posted by TrickyLogic on 23 September 2012 - 07:35 AM

You can try to use Bresenham's line algorithm. Go from the source to the destination you can then count the number of solid tiles along the way.


PARTNERS