Search code examples
pythonarraysnumpypygameperlin-noise

How can I get a 2D tile output from perlin-noise?


My plan is to have Perlin noise generating 2D terrain, I have looked around the internet looking for solutions but either can't understand the code or tried it and not had it work.

import pygame
import numpy as np
from pygame import *

# source images to the game display
# Tiling thing from https://markbadiola.com/2012/01/22/rendering-background-image-using-pygame-in-python-2-7/

# assigns source image
SOURCE = pygame.image.load('tiles.png')

p = pygame.Rect(288, 0, 32, 32) # pavement
g = pygame.Rect(416, 0, 32, 32) # grass
s = pygame.Rect(288, 160, 32, 32) # sand/dirt
b = pygame.Rect(288, 320, 32, 32) # bush

# matrix containing the pattern of tiles to be rendered

import numpy as np
import sys
np.set_printoptions(threshold=sys.maxsize)
from scipy.ndimage.interpolation import zoom
arr = np.random.uniform(size=(4,4))
arr = zoom(arr, 8)
arr = arr > 0.5
arr = np.where(arr, '-', '#')
arr = np.array_str(arr, max_line_width=500)
print(arr)

This code gives a good looking array but the rest of my code does not work with it. The error message I get is Invalid rectstyle argument. This would work I believe if I was able to change '-' and '#' to g and s but that also does not work.

for y in range(len(map1.arr)):
  for x in range(len(map1.arr[y])):
    location = (x * 32, y * 32)
    screen.blit(map1.SOURCE, location, map1.arr[y][x])

Solution

  • Surface.blit wants a rect as area argument. You pass a string.

    What you could do is create a map to translate the strings to the right rects that you already defined, something like this:

    mapping = { '#': s, '-': g }
    
    tile = map1.arr[y][x]
    area = mapping[tile]
    screen.blit(map1.SOURCE, location, area)
    

    You also want to remove the

    arr = np.array_str(arr, max_line_width=500)
    

    line since this converts arr to a string.