我一直在研究Perlin噪声,因为我正在开发一个基于“2维侧视”的游戏(模拟应用)。我并不完全理解Perlin噪声是如何工作的,但大致了解。
我找到了这篇文章和代码Perlin Noise,决定试一下。目前我已经设置了世界生成方式,每个“块”有16x16个图块,当Y >= HEIGHT / 2时所有图块都是“实心”,否则是“空气”,这个方案可以正常工作。但地形非常平坦,正如你所想象的那样。这就是我认为Perlin噪声可以派上用场的地方,所以我使用了上述网站上找到的代码,但我并不确定该如何将噪声转换为实心/空气图块。
如你所见,这是非常不真实的地形:
我更希望地形像下面这样(看起来像山和滚动山丘),我不关心边缘是否锐利(方形):
我不知道如何遍历图块数组来将噪声转换为上述地形。
目前,我正在像这样遍历图块数组(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
我还应该提到,在这个16x16的“块”的右侧,还有另一个需要与之匹配的块,接下来的下一个块也是如此。块不应与以前的块相同,只需使其看起来不像是单独的块即可,如果这样说有意义的话。
非常感谢您的帮助!谢谢
更新
我已经将我的perlin函数更改为这个,并实现了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
,否则每个区块都会是相同的,现在看起来像下面这样:
![enter image description here](https://istack.dev59.com/rfSSv.webp)
我删除了噪声值下方的图块创建,因此更容易看到范围。
![enter image description here](https://istack.dev59.com/tFpBn.webp)
谢谢。
tile = block
,这就定义了后面程序中渲染的瓷砖。在你的回答中,你似乎只迭代x(上面的每个像素都将成为天空的一部分,下面的每个像素都将是[固体])。我初始化地图的方式是[0][0]->[15][15],所以是y然后x。如果按照你的建议去做,似乎会再次变成混乱,我需要改变这个吗? - Elgoog