Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用柏林噪波生成二维地形(基于瓷砖)_C++_Perlin Noise - Fatal编程技术网

C++ 使用柏林噪波生成二维地形(基于瓷砖)

C++ 使用柏林噪波生成二维地形(基于瓷砖),c++,perlin-noise,C++,Perlin Noise,我一直在研究柏林噪声的一个应用程序,我正在开发一个基本上是“二维侧视”的游戏(模拟)。我不完全理解柏林噪声是如何工作的,但我能大致了解 我找到了这篇包含代码的文章,并决定在几年前发布,目前我设置world gen的方式是,每个“块”都有16x16个瓷砖,我刚刚声明,如果Y>=HEIGHT/2使所有瓷砖为“实心”,否则为“空气”,这样就行了。。但是,正如你想象的那样,这片土地非常平坦。这就是我认为柏林墙噪音的原因,所以我使用了上面网站上的代码,但我不确定如何将噪音转化为实心/空心瓷砖 正如你所看到

我一直在研究柏林噪声的一个应用程序,我正在开发一个基本上是“二维侧视”的游戏(模拟)。我不完全理解柏林噪声是如何工作的,但我能大致了解

我找到了这篇包含代码的文章,并决定在几年前发布,目前我设置world gen的方式是,每个“块”都有16x16个瓷砖,我刚刚声明,如果Y>=HEIGHT/2使所有瓷砖为“实心”,否则为“空气”,这样就行了。。但是,正如你想象的那样,这片土地非常平坦。这就是我认为柏林墙噪音的原因,所以我使用了上面网站上的代码,但我不确定如何将噪音转化为实心/空心瓷砖

正如你所看到的,地形不是很真实

我更喜欢下面的地形。应该看起来像山和起伏的小山)我不担心尖锐的边缘(正方形)

我不知道如何通过迭代的瓷砖阵列,把噪音变成上面

目前,我正在像这样遍历瓷砖阵列(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
for(int Y=0;Y
我还应该提到,在这个16x16“块”的右侧,还有一个块需要与这个块匹配,之后的下一个块也需要匹配。块不应该与前面的块相同,只要让它们看起来不是单独的块,如果这有意义的话

非常感谢您的帮助!谢谢

更新

我已将我的柏林函数更改为的,并实现了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;
            }
        }
PerlinNoise*test=newperlinnoise(0.25,6);/0.25是持续性6是八度音阶
浮点数f,h;
漂浮种子=804.343;
对于(int X=0;X!=MAP_WIDTH;++X){
f=测试->获取噪声((X*ChunkX)*种子);
h=f*地图高度+(地图高度/2);

对于(int y=0;y您的结果很好,因为您有岛屿、大陆、池塘和海洋。柏林噪声帮助您生成非随机特征的随机地形

基本上,你可以将噪波函数的无限分辨率(数学上)减少为两个不同分片的离散集,再加上块的非常有限的分辨率。考虑到这一点,你的结果看起来很好

不同的事情可能会改善结果。例如,在平铺图形之间进行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函数推广到任何平铺计数

锐利边缘的另一种可能性来自(1)。您具有与上述相同的功能,但不是插值,而是使用最接近噪波值的瓷砖:

Color color_at (x, y) {
    Real u = x / width, v = y / height
    Real  f  = min (max(noise(u,v), 0), 1);
    if (f<0.5) return water;
    else return hill;
}
(x,y)处的颜色{ 实际u=x/宽度,v=y/高度 实际f=最小值(最大值(噪声(u,v),0),1);
如果(f抱歉,如果我没有充分解释这个问题,我需要的是一个“侧视图”,而不是鸟瞰图。我想我理解,你肯定知道你的东西。我实际上不使用setPixel,我要做的是一旦在for循环中设置了磁贴,比如说
tile=block
,它定义了程序中稍后渲染的磁贴。我在您的回答中,您似乎只迭代x(上面的每个像素都是天空的一部分,下面的每个像素都是[实心]),我启动地图的方式是[0][0]->[15][15]那么y然后x,如果我按照你的建议做了,它似乎又会变成一个混乱,我需要改变这个吗?@Elgoog:是的,我的解决方案假设你可以画单个像素。你可以在CPU上,或者甚至在GPU上足够快地做这件事(但我没有真正的GPGPU经验)。你真正的问题是块状,还是有太多的“棕色”呢瓷砖?
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, y, tileColor(x,y, tile));
}