I am creating a 3D rendering system in Tkinter and adding in textured walls. However, when I want to create another image the original disappears, and It will only render 1 wall and it appears that there can only be one wall.
Code:
import getkey
import threading
import PIL
from PIL import Image, ImageTk
from tkinter import *
global key
key = ""
x_cord = 0
y_cord = 0
def input_check(): #gets keyboard input
global key
while True:
unprocessed_key = str(getkey.getkey())
if len(key) > 0:
key = key unprocessed_key
else:
key = unprocessed_key
window = Tk()
window.title(" ")
photo = PIL.Image.open("wall.png")
logoImg = ImageTk.PhotoImage(photo)
window.iconphoto(False, logoImg)
window.state("normal")
geo_draw = Canvas(window, width=400, height=400, background="#000000") #creats the geomatry drawer
input_thread = threading.Thread(target=input_check, args=()) #allows keyboard input
input_thread.start()
geo_draw.pack(fill=BOTH, expand=1)
render_list = [[0,1,"#0000FF",1],[0,1,"wall",0]] #if you add ,[1,1,"wall",0] to the render list so that it creates another the first will disapear
winX = 0
winY = 0
while True:
geo_draw.delete("all")
geo_draw.configure(scrollregion=(-(winX//2), -(winY//2), (winX//2), (winY//2)))
geo_draw.xview_moveto(1)
geo_draw.yview_moveto(1)
for x in range(len(render_list)):
y_render_cord = render_list[x][1] - y_cord
if render_list[x][3] == 0: #draws a image for the front face of the wall
xdiv = (x_cord render_list[x][0] 0.481) *-250 / y_render_cord
ydivB = round(240 / y_render_cord)
front_render_image = PIL.Image.open(f"{render_list[x][2]}.png")
try:
realImg = front_render_image.resize((ydivB, ydivB), PIL.Image.Dither.NONE) #scales the image
except:
realImg = front_render_image.resize([200,200]) #stops the image rendering to large
realImg = ImageTk.PhotoImage(realImg)
geo_draw.create_image(xdiv, 0, image = realImg, anchor = CENTER) #draws the image
else: #draws the side of the walls
wall_cord = (x_cord render_list[x][0]) *-250
ydiv = 120 / (y_render_cord render_list[x][3])
ydivB = round(120 / y_render_cord)
xdiv = wall_cord / y_render_cord
xdivB = wall_cord / (y_render_cord render_list[x][3])
geo_draw.create_polygon([xdiv, ydivB, xdivB, ydiv, xdivB, -ydiv, xdiv, -ydivB], fill=render_list[x][2])
for letter in key: # gets keyboard input
if letter == "w":
y_cord = 0.1
elif letter == "a":
x_cord -= 0.1
elif letter == "s":
y_cord -= 0.1
elif letter == "d":
x_cord = 0.1
key = ""
window.update()
window.update_idletasks()
winX = geo_draw.winfo_width()
winY = geo_draw.winfo_height()
You will need to make a texture called "wall.png", but it can be any image.
Thanks
CodePudding user response:
I have experienced a similar situation when I was doing my project. You are rewriting the realImg
every single time it loops. It is a problem because as soon as you create a new image in that SAME variable then the old one is gone. So you have to make sure it's still present like a memory because ImageTk will not create a memory of its own. So you have to append that variable to a list so that it is stored.
So do something like this:
image_storing = []
LATER: image_storing.append(realImg)
Hopefully this works for you.