-2

i understood using perlin-noise to make a pattern with cubes but what i want to is a random terrain plain land such as this game called muck (that has been devolped by unity)enter image description here

i've tried doing:

noise = PerlinNoise(octaves=3, seed=2007)
amp = 3
freq = 24
width = 30


for po in range(width*width):
s = randint(200, 255)
q = Entity(model="cube", collider="box", texture="white_cube",
           color=color.rgb(s, s, s))
q.x = floor(po/width)
q.z = floor(po % width)
q.y = floor(noise([q.x/freq, q.z/freq]) * amp)

so this would give a -almost- perfect random terrain but i want my terrain look more realistic than cubic thanks in advance ;)

Bahjat
  • 25
  • 4
  • 2
    What have you tried so far? Please show us your code in the form of a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Jan Wilamowski Dec 24 '21 at 04:37
  • 2
    Also what does this have to do with `python` and `pygame`? I removed these tags as they seem not relevant to me – derHugo Dec 24 '21 at 05:31

1 Answers1

2

Unsurprisingly, your landscape looks cubic because you're constructing it from cubes. So to make it more realistic, use a more flexible Mesh for it. You will have to assign each point of the surface separately and connect it to its surrounding via triangles:

level_parent = Entity(model=Mesh(vertices=[], uvs=[]), color=color.white, texture='white_cube')

for x in range(1, width):
    for z in range(1, width):
        # add two triangles for each new point
        y00 = noise([x/freq, z/freq]) * amp
        y10 = noise([(x-1)/freq, z/freq]) * amp
        y11 = noise([(x-1)/freq, (z-1)/freq]) * amp
        y01 = noise([x/freq, (z-1)/freq]) * amp
        level_parent.model.vertices += (
            # first triangle
            (x, y00, z),
            (x-1, y10, z),
            (x-1, y11, z-1),
            # second triangle
            (x, y00, z),
            (x-1, y11, z-1),
            (x, y01, z-1)
        )

level_parent.model.generate()
level_parent.model.project_uvs() # for texture
level_parent.model.generate_normals() # for lighting
level_parent.collider = 'mesh' # for collision

However, this will be quite slow to generate, mostly due to the Perlin noise implementation used (I'm assuming this one). A faster option can be found in this answer.

Jan Wilamowski
  • 3,308
  • 2
  • 10
  • 23