我发现这篇文章的代码为Perlin Noise,并决定在此之前给出它,我现在设置世界的方式是每个“块”有16×16块,我刚刚声明如果Y> = HEIGHT / 2使所有瓷砖’坚固的’其他’空气’,这样才能正常工作……但是土地非常平坦,就像你想象的那样.多数民众赞成在那里我认为perlin噪音会进来,所以我使用了上面网站上的代码,但我不确定如何将噪音转换为固体/空气瓦片.
你可以看到不太现实的地形
我正在寻找下面的地形.应该看起来像山脉和连绵起伏的丘陵)我不担心锋利的边缘(方形)
我不知道如何遍历tile数组以将噪声转换为上面
目前我正在迭代瓷砖阵列(2d),但正如你从第一张图片中看到的那样,它只是随机化瓷砖是否是实心的,它不会产生任何起伏的山丘或山脉.
for(int Y = 0;Y < HEIGHT;++Y) { for(int X = 0;X < WIDTH;++X) { Tile Tile; if(noise(X,Y) < 0) { Tile.Type = BLOCK; } else { Tile.Type = Air; } // Then I push the Tile on to a vector
我还应该提到,在这个16×16’块’的右边,还有另一个需要与这个块相匹配的块,之后与下一个块相同.块不应该和以前一样只是让它看起来像是不是单独的块,如果这有意义的话.
任何帮助是极大的赞赏!谢谢
UPDATE
我已将perlin函数更改为this的函数,并且我已实现phresnel建议的内容:
PerlinNoise *test=new PerlinNoise(0.25,6); //0.25 is Persistance 6 is Octaves float f,h; float seed = 804.343; for (int X=0; X!=MAP_WIDTH; ++X) { f = test->GetNoise((X * ChunkX) * seed); h = f * MAP_HEIGHT + (MAP_HEIGHT / 2); for (int y=0; y<h; ++y) { Tile tempTile; tempTile.Tile = TILE_NONE; Tiles[X][y] = tempTile; } for (int y=h; y<MAP_HEIGHT; ++y) { Tile tempTile; tempTile.TileID = TILE_BLOCK; Tiles[X][y] = tempTile; } }
这样做后看起来好多了,我为每个噪音X * ChunkX,好像我没有每个块都是一样的,所以现在它看起来像以下
你可以看到地形比我以前想要的更多,但仍然看起来不像真正的地形,因为它不是很光滑,有什么我可以做的,以平滑它的整体外观,以创建连绵起伏的丘陵和平原
我在该噪声值下删除了tile的创建,因此更容易看到范围
正如您所看到的那样,看起来没问题,只需要对值进行“平滑”处理,使它们看起来不像伪随机值.我也想知道为什么左边看到的第一个块具有相同的值.
谢谢.
解决方法
您基本上将噪声函数的(数学上)无限分辨率降低为仅包含两个不同图块的离散集合,以及块的非常有限的分辨率.鉴于此,您的结果似乎很好.
不同的事情可能会改善你的结果例如,瓷砖图形之间的lerp:
// Exemplary p-code,fine-tuning required Color color_at (x,y) { Real u = x / width,v = y / height Real f = min (max(noise(u,v),0),1); Color c = water*f + hill*(1-f); return c; }
您可以将lerp函数概括为任何tile-count.
锐边的另一种可能性受到Voronoi diagrams(1)的启发.您具有与上面相同的功能,但不是内插,而是采用最接近噪声值的图块:
Color color_at (x,1); if (f<0.5) return water; else return hill; }
这和你的一样,除了你按像素方式做.同样,这可以概括.
一旦你有一个很好的设置,你可以使用噪音:植物/树木分布,敌人分布,动画(这将是一个噪音功能)等.
编辑您的评论:
连续的1d地形:
如果您需要像经典的2d-jump和run一样的侧视图,请考虑1d噪声函数,从0到图像宽度迭代,在每个停止处获取噪声函数的样本f,将f转换为屏幕空间,那么上面的每个像素都将成为天空的一部分,下面的每个像素都会从你的瓷砖中取出:
for (int x=0; x!=width; ++x) { // Get noise value: f = noise1d (x/width); h = f * height + (height/2); // scale and center at screen-center // Select tile: Tile *tile; if (h < waterLimit) { h = waterLimit; tile = waterTile; } else { tile = terrainTile; } // Draw vertical line: for (int y=0; y<h; ++y) setPixel (x,y,skyColor(x,y)); for (int y=h; y<height; ++y) setPixel (x,tileColor(x,tile)); }
再次,示例性伪代码.
当前设置中的完整2d级别:
噪音功能非常灵活.如果你想要更少的蓝色和更多的绿色,只需降低常数项,即代替if(h <0) - >蓝色,如果(h <-0.25) - >蓝色. 1:我从未尝试过这种方法,因为我正在进行三维地形渲染(picogen.org)