噪声模块中的 pnoise2() 函数产生 SegFault python 3.8

pnoise2() function in noise module produces SegFault python 3.8

我正在尝试为我正在开发的游戏程序生成一些地图,并且我正在尝试使用 noise 模块中的 perlin 噪声函数。

通过网上的一些教程,我发现我必须这样使用它:

import random
import noise
from noise import pnoise2

factor = 15 #it doesn't need to be 15, it can be anything different from greater than 1 or lower than -1, otherwise it will return 0.0
oct=1
seed=random.randint(0, 100)


print(pnoise2(x/factor, y/factor, octaves=oct, base=seed))

我可以给它传递值xy但是如果因子满足注释中的条件,程序会在调用pnoise2函数时抛出致命错误segfault。我做错了什么?

我也在游戏中使用pygame,我得到的确切错误如下:

Fatal Python error: (pygame parachute) Segmentation Fault
Python runtime state: initialized

Current thread 0x00007fe3247f2740 (most recent call first):
  File "scripts/world_manager.py", line 78 in generate
  File "main.py", line 153 in reload_chunks
  File "main.py", line 257 in update
  File "main.py", line 207 in run
  File "main.py", line 406 in <module>
Aborted

这里是world_manager.py中的generate()函数:

# Generate a chunk at given coordinates using pnoise2 and adding it to the chunk list
    def generate(self, chunkx, chunky):

        # print("Generating chunk at", chunkx, chunky)

        GRASS = "grass"
        MOUNTAIN = "mountain"
        EMPTY = "void"

        floor_void_diff = 0.3
        mountain = floor_void_diff + 0.2

        factor = 3

        floor = {}
        items = {}
        chunk = (chunkx, chunky)

        if chunk not in self.chunks:

            # print("Generating chunk at {}".format(chunk))
            for y in range(chunky * CHUNKSIZE, chunky * CHUNKSIZE + CHUNKSIZE):
                for x in range(chunkx * CHUNKSIZE, chunkx * CHUNKSIZE + CHUNKSIZE):
                    i = pnoise2(x/factor, y/factor, base=int(self.seed))
                    print(i)
                    if i >= floor_void_diff:
                        if i > mountain:
                            floor.update({(x, y): MOUNTAIN})
                        else:
                            floor.update({(x, y): GRASS})
                        spawner = random.randint(-1, ITEM_SPAWN_RATIO)
                        random_item = random.randint(0, len(ITEM_LIST)-1)

                        if spawner == 0:
                            items.update({(x, y): ITEM_LIST[random_item]})

                    elif i < floor_void_diff:
                        floor.update({(x, y): EMPTY})
                    else:
                        floor.update({(x, y): EMPTY})

            self.chunks.update({chunk: {"floor": floor, "items": items}})
            self.unsaved += 1

CHUNKSIZE 在 settings.py 文件中定义,现在 CHUNKSIZE=4

我还没有找到解决这个问题的方法,但找到了替代方法。我发现我使用噪声模块的方式在某种程度上破坏了它,所以我开始寻找 perlin 噪声函数,我在 https://rosettacode.org/wiki/Perlin_noise#Python

找到了一个非常好的函数

看起来您正在传递 seed,因为 octaves 参数实际上是什么。我不知道这是如何导致分段错误的,但是大量会导致加法循环进行大量迭代。我不知道这个库(如果它确实 https://github.com/caseman/noise)实际上支持播种,但也许我缺少它支持的地方。

另外,为什么不用snoise2函数呢? pnoise2(实际的 Perlin 噪声)会产生很多 45 度和 90 度的偏差(image comparison, Perlin on top). The "Perlin" algorithm has the iconic name, but it's probably rarely the best choice for noise anymore. The snoise2 (Simplex noise 2D) is more subtle about grid alignment. This library(间接无耻插件)确实会在 Simplex 类别中产生可播种噪声,并且输出质量比我想说的另一个库中的质量高一点,但缺点可能是它直接在 Python 中实现,而不是包装一个可能更快的 C 实现。你还需要实现八度求和/分形布朗运动,如果你追求那个效果的话。另一个库为它提供了 octaves 参数。