6

Sorry if that title isn't very descriptive. Anyway, I am working on something dealing with randomly generating landscapes. I made lakes, but due to how they are make, they often cause straight edges / dropoffs, which aren't desirable. I am trying to smooth it (right after making the lake, if possible), by defining a max variation amount (so land heights cannot vary more than it), and have it fix land if it varies to much, and quit if it is fine.

The problem:

Large dropoff

My attempted fix:

Attempted fix

As you can see... it didn't work. It also occurs to me, I think it would be broken if it had to move down, although that case shouldn't actually occur, because lakes only ever sink the landscape. Anyway, here is the source of my attempt:

//smoothing land nearby

            int maxVariation = 2; //similar to the max height variation when the land is generated

            //going right



            for (int xPos = rightBound + 1, previousHeight = 0; ; ++xPos)
            {
                if (previousHeight == 0)
                    for (; previousHeight < size.y; ++previousHeight)
                        if (grid[0][rightBound][previousHeight] != BlockColor::DIRT && grid[0][rightBound][previousHeight] != BlockColor::GRASS)
                        {
                            --previousHeight;

                            break;
                        }


                for (int y = 0; y < size.y; ++y)
                    if (grid[0][xPos][y] == BlockColor::WATER)
                        goto done_smoothing_right;

                int height;

                for (height = 0; height < size.y; ++height)
                    if (grid[0][xPos][height] != BlockColor::DIRT && grid[0][xPos][height] != BlockColor::GRASS)
                    {
                        --height;

                        break;
                    }

                    int difference = std::abs(height - previousHeight);

                    previousHeight = height;

                    if (difference > maxVariation)
                    {
                        for (int j = 0; j < size.y; ++j)
                        {
                            int toMove = difference;

                            while (j + toMove >= size.y)
                                --toMove;

                            grid[0][xPos][j] = grid[0][xPos][j + toMove];
                        }
                    }
                    else
                        goto done_smoothing_right;


            }

done_smoothing_right:

            int tomakegotowork;

Note that is only the right side, but left should be about the same. How can I do this correctly?

Thanks if you can help.

EDIT:

I never did solve this problem. Instead, I made a recursive function to measure air, (from a certain height), and if a pocket of air (formed by the land) had enough, to fill with water. This has the advantaged of the land looking smooth because it is not altered.

  • rightBound is the lake's rightBound? Do lakes only occur at height 0? – Mike Saull Jul 11 '13 at 17:28
  • @MikeSaull Yes, rightBound is the x of the rightmost water. Lakes don't only occur at 0, but with the current land height and lake depth, it does look like that. –  Jul 11 '13 at 17:39

1 Answers1

1

This is written in java so you will need to convert it to c++ but it should give you the basic idea. It will only work for smoothing upwards as well and I only did the right side of the lake but it is very easy to modify it for the left side of the lake. I tried to match what I think the functionality of your code is.

Hope it helps...

void smoothLakeRight(Lake lake){

    int x = lake.rightBound+1;

    if(getGrassHeight(x)-lake.height>WorldConstants.MAX_LAKESIDE_VARIATION){
        //if the right bank is too high start smoothing
        int y =lake.height+WorldConstants.MAX_LAKESIDE_VARIATION;

        while(grid[0][x][y] == BlockColor.DIRT){
            fixGrass(x++, y++);
        }
    }
}

private int getGrassHeight(int xPos){

    int y = WorldConstants.LOWEST_GRASS;

    while(grid[0][xPos][y++] != BlockColor.GRASS);

    return y-1;
}

private void fixGrass(int xPos, int yPos){

    grid[0][xPos][yPos] = BlockColor.GRASS;

    aboveAir(xPos,yPos);
    belowDirt(xPos, yPos);

}

private void aboveAir(int xPos, int yPos) {

    while(grid[0][xPos][++yPos]!=BlockColor.AIR){
        if(grid[0][xPos][yPos]==BlockColor.TREE){
            upRootTree(xPos, yPos);
        }else{
            grid[0][xPos][yPos]=BlockColor.AIR;
        }
    }
}

private void upRootTree(int xPos, int yPos) {

    while(grid[0][xPos][yPos]==BlockColor.TREE){//remove stump
        grid[0][xPos][yPos++]=BlockColor.AIR;
    }

    //remove leaves
    grid[0][xPos][yPos] = BlockColor.AIR;
    grid[0][xPos+1][yPos] = BlockColor.AIR;
    grid[0][xPos-1][yPos] = BlockColor.AIR;
    grid[0][xPos+1][yPos-1] = BlockColor.AIR;
    grid[0][xPos-1][yPos-1] = BlockColor.AIR;
}

private void belowDirt(int xPos, int yPos) {

    while(grid[0][xPos][--yPos]!=BlockColor.DIRT){
        grid[0][xPos][yPos] = BlockColor.DIRT;
    }
}
Mike Saull
  • 1,415
  • 2
  • 11
  • 11