微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Perlin Noise(基于Tile)生成c – 2d地形

我一直在研究perlin噪音的应用程序,我正在研究它基本上是一个’二维侧视图’看游戏(模拟).我不完全理解perlin噪声是如何工作的,但是得到了一般的想法.

我发现这篇文章代码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的创建,因此更容易看到范围

正如您所看到的那样,看起来没问题,只需要对值进行“平滑”处理,使它们看起来不像伪随机值.我也想知道为什么左边看到的第一个块具有相同的值.

谢谢.

解决方法

你的结果很好,因为你有岛屿,大陆,池塘和海洋. Perlin噪音可以帮助您生成随机字符的随机地形.

您基本上将噪声函数的(数学上)无限分辨率降低为仅包含两个不同图块的离散集合,以及块的非常有限的分辨率.鉴于此,您的结果似乎很好.

不同的事情可能会改善你的结果例如,瓷砖图形之间的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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐