Сглаживание земли вокруг озер

Извините, если этот заголовок не очень описательный. Во всяком случае, я работаю над тем, что касается случайного создания ландшафтов. Я сделал озера, но из-за того, как они сделаны, они часто вызывают прямые края / выпадения, что нежелательно. Я пытаюсь сгладить его (сразу после создания озера, если это возможно), определяя максимальную величину отклонения (чтобы высота земли не могла варьироваться больше, чем она), и заставляю ее фиксировать землю, если она сильно меняется, и выходить, если она хорошо.

Эта проблема:

Большой спад

Моя попытка исправить:

Попытка исправить

Как видите … это не сработало. Это также происходит со мной, я думаю, что оно сломалось бы, если бы ему пришлось спуститься, хотя в действительности это не должно происходить, потому что озера только тонут в ландшафте. Во всяком случае, вот источник моей попытки:

//smoothing land nearby

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

//going rightfor (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;

Обратите внимание, что только с правой стороны, но слева должно быть примерно одинаково. Как я могу сделать это правильно?

Спасибо, если вы можете помочь.

РЕДАКТИРОВАТЬ:

Я никогда не решал эту проблему. Вместо этого я сделал рекурсивную функцию, чтобы измерить воздух (с определенной высоты), и, если достаточно места в воздухе (образованном землей), заполнить водой. Это дает преимущество того, что земля выглядит гладкой, потому что она не изменена.

6

Решение

Это написано на Java, поэтому вам нужно будет преобразовать его в C ++, но это должно дать вам основную идею. Это будет работать только для сглаживания вверх, и я сделал только правую сторону озера, но очень легко изменить его для левой стороны озера. Я пытался соответствовать тому, что я думаю о функциональности вашего кода.

Надеюсь, поможет…

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;
}
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]