Извините, если этот заголовок не очень описательный. Во всяком случае, я работаю над тем, что касается случайного создания ландшафтов. Я сделал озера, но из-за того, как они сделаны, они часто вызывают прямые края / выпадения, что нежелательно. Я пытаюсь сгладить его (сразу после создания озера, если это возможно), определяя максимальную величину отклонения (чтобы высота земли не могла варьироваться больше, чем она), и заставляю ее фиксировать землю, если она сильно меняется, и выходить, если она хорошо.
Эта проблема:
Моя попытка исправить:
Как видите … это не сработало. Это также происходит со мной, я думаю, что оно сломалось бы, если бы ему пришлось спуститься, хотя в действительности это не должно происходить, потому что озера только тонут в ландшафте. Во всяком случае, вот источник моей попытки:
//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;
Обратите внимание, что только с правой стороны, но слева должно быть примерно одинаково. Как я могу сделать это правильно?
Спасибо, если вы можете помочь.
РЕДАКТИРОВАТЬ:
Я никогда не решал эту проблему. Вместо этого я сделал рекурсивную функцию, чтобы измерить воздух (с определенной высоты), и, если достаточно места в воздухе (образованном землей), заполнить водой. Это дает преимущество того, что земля выглядит гладкой, потому что она не изменена.
Это написано на 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;
}
}
Других решений пока нет …