[Python] my perlin noise in python force close my window

Discussão em 'Python' iniciado por Stack, Maio 20, 2025.

  1. Stack

    Stack Membro Participativo

    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...

Compartilhe esta Página