my perlin noise is working good but if i make the generation bigger it will slow down to a point that my window will force close it so im force to make the perlin noise smaller. is there ways to make the generate slower so it wont force close or make the code not do the work if its not on screen. (this is a shorter version so its easy to read also i have pygame install if that will help). import tkinter as tk from PIL import Image, ImageTk import numpy as np import os #perlin noise terrain --- tile_size = 4 tiles_x, tiles_y = 150, 150 scale = 64 image_width = tiles_x * tile_size image_height = tiles_y * tile_size screen_width = 1920 screen_height = 1080 def create_window(): def setting(): #????? game_setting = tk.Toplevel(game_window) #the setting look game_setting.geometry("500x1000") game_setting.title("setting") game_setting.config(background="black") set_continue = tk.Button(game_setting, text="continue", command=game_setting.destroy, font=("arial", 15, "bold"), bg="black", fg="white", padx=84) set_continue.place(x=100, y=120) set_close = tk.Button(game_setting, text="close", command=main_window.destroy, font=("arial", 15, "bold"), bg="black", fg="white", padx=100) set_close.place(x=100, y=200) #????? game_window = tk.Toplevel(main_window) #the game_window look game_window.attributes("-fullscreen", True) game_window.geometry("1920x1080") game_window.title("game") game_window.config(background="black") #where the image sit terrain_types = [ (0.35, "grass_wall.png"), (0.45, "grass.png"), (0.50, "sand.png"), (0.70, "water.png"), ] #load the image on the folder "image" def load_textures(folder="image/terrarian"): textures = {} for threshold, filename in terrain_types: path = os.path.join(folder, filename) img = Image.open(path).convert("RGBA").resize((tile_size, tile_size)) textures[filename] = img return textures #create the perlin noise def generate_perlin_noise(width, height, scale=10): def fade(t): return t * t * t * (t * (t * 6 - 15) + 10) def lerp(a, b, t): return a + t * (b - a) def grad(hash, x, y): h = hash & 3 u = x if h & 1 == 0 else -x v = y if h & 2 == 0 else -y return u + v def perlin(x, y, p): xi = int(np.floor(x)) & 255 yi = int(np.floor(y)) & 255 xf = x - np.floor(x) yf = y - np.floor(y) u, v = fade(xf), fade(yf) aa = p[p[xi] + yi] ab = p[p[xi] + yi + 1] ba = p[p[xi + 1] + yi] bb = p[p[xi + 1] + yi + 1] x1 = lerp(grad(aa, xf, yf), grad(ba, xf - 1, yf), u) x2 = lerp(grad(ab, xf, yf - 1), grad(bb, xf - 1, yf - 1), u) return (lerp(x1, x2, v) + 1) / 2 p = np.arange(256, dtype=int) np.random.shuffle(p) p = np.concatenate([p, p]) noise = np.zeros((height, width), dtype=np.float32) for y in range(height): for x in range(width): noise[y, x] = perlin(x / scale, y / scale, p) return noise #the perlin noise set the terrain def build_terrain_image(noise, textures): img = Image.new("RGBA", (image_width, image_height)) sgrid = [] for y in range(tiles_y): row = [] for x in range(tiles_x): value = noise[y, x] for threshold, filename in terrain_types: if value <= threshold: texture = textures[filename] break img.paste(texture, (x * tile_size, y * tile_size)) sgrid.append(row) return img, sgrid #generate terrain image before displaying --- noise = generate_perlin_noise(tiles_x, tiles_y, scale) textures = load_textures() terrain_image, sgrid = build_terrain_image(noise, textures) #show terrain in canvas tk_terrain = ImageTk.PhotoImage(terrain_image) canvas_width = game_window.winfo_screenwidth() canvas_height = game_window.winfo_screenheight() canvas = tk.Canvas(game_window, width=canvas_width, height=canvas_height) canvas.pack() terrain_id = canvas.create_image(0, 0, image=tk_terrain, anchor="nw") def is_blocked(x, y, grid): return grid[y][x] == 1 # or some value meaning "solid" set = tk.Button( game_window, text="s", command=setting, font=("arial", 10, "bold"), bg="black", fg="white") set.place(x=0, y=0) game_window.mainloop() #????? main_window = tk.Tk() #the main_window look main_window.attributes("-fullscreen",True) main_window.geometry("500x500") main_window.title("game") main_window.config(background="black") main_play = tk.Button( main_window, text="open", command=create_window, font=("arial",20,"bold"), bg="black", fg="white", padx=100) main_play.place(x=530,y=250) main_close = tk.Button( main_window, text="close", command=main_window.destroy, font=("arial",20,"bold"), bg="black", fg="white", padx=98) main_close.place(x=530,y=325) main_window.mainloop() Continue reading...