Erich Schmidt Erich Schmidt - 1 year ago 53
Python Question

Best method to keep checking the state of a variable in tkinter window

I'm currently creating an RPG game and now I want the character to go to certain places. When it reaches those places, this window should close and the End should appear (It is in a different file). What is the best method of doing that? I currently having the problem of keeping checked that the variable giving me the state of having entered a certain area is

False
, if it's True, the other code should be executed.

Here is what I currently have:

class player(object):
def __init__(self, x, y):
self.root = None
self.x = x
self.y = y

def zeichne(self, root):
self.root = root
self.l1 = root.create_line(self.x-5, self.y-5, self.x+5, self.y+5, width=2)
self.l2 = root.create_line(self.x+5, self.y-5, self.x-5, self.y+5, width=2)

def configure(self, x, y):
self.root.delete("all")
self.x = x
self.y = y
self.root.create_line(self.x-5, self.y-5, self.x+5, self.y+5, width=2)
self.root.create_line(self.x+5, self.y-5, self.x-5, self.y+5, width=2)

def go_fwd(event):
areal.focus_set()
me.configure(me.x, me.y-2)

def go_bwd(event):
areal.focus_set()
me.configure(me.x, me.y+2)

def go_left(event):
areal.focus_set()
me.configure(me.x-2, me.y)

def go_right(event):
areal.focus_set()
me.configure(me.x+2, me.y)

dw = tk.Tk()
dw.title('Erebos')

areal = tk.Frame(master=dw, width=20000, height=600, bg='black')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw)-100)
areal.bind("<1>", lambda event: areal.focus_set())
dw.bind("<Up>", go_fwd)
dw.bind("<Down>", go_bwd)
dw.bind("<Left>", go_left)
dw.bind("<Right>", go_right)

playarea = tk.Canvas(width=800, height=500, master=areal, bg='white')
playarea.pack()

dw.mainloop()


I thought it might be useful to use background processes but there are so many packages, that I'm really confused. What to do here and whish background package to use?

Answer Source

I hope i get your question right. You have to check the players position on every move. I recommend that you define areas, on every move (e.g. go_right) you need to check if the player is in those boundaries. If that is True you can load another script. Here is a quick and dirty solution:

def go_fwd(event):
    areal.focus_set()
    me.configure(me.x, me.y-2)
    check_if_player_enters_region(me)

def go_bwd(event):
    areal.focus_set()
    me.configure(me.x, me.y+2)
    check_if_player_enters_region(me)

def go_left(event):
    areal.focus_set()
    me.configure(me.x-2, me.y)
    check_if_player_enters_region(me)

def go_right(event):
    areal.focus_set()
    me.configure(me.x+2, me.y)
    check_if_player_enters_region(me)

def check_if_player_enters_region(player):
    ## Define your Areas here
    if(is_in_region(player, 20, 20, 10, 10)):
        print "enter region 1, load script xxx"
    if(is_in_region(player, 50, 50, 10, 10)):
        print "enter region 2, load script xxx"   

    playarea.create_rectangle(20,20,30,30, fill='blue') ## this is just for visualisation, delete this line
    playarea.create_rectangle(50,50,60,60, fill='blue') ## this is just for visualisation, delete this line

def is_in_region(player, x, y, width, height): # define region boundries
    if((player.x >= x and player.x <= x+width) and  ## check x boundries
       (player.y >= y and player.y-2 <= y+height)): ## check y boundries
        return True
    return False

dw = tk.tk()
dw.title('Erebos')

me = player(0,0)

areal = tk.Frame(master=dw, width=20000, height=600, bg='black')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw)-100)
areal.bind("<1>", lambda event: areal.focus_set())
dw.bind("<Up>", go_fwd)
dw.bind("<Down>", go_bwd)
dw.bind("<Left>", go_left)
dw.bind("<Right>", go_right)

playarea = tk.Canvas(width=800, height=500, master=areal, bg='white')
playarea.pack()
playarea.create_rectangle(20,20,30,30, fill='blue') ## this is just for visualisation, delete this line
playarea.create_rectangle(50,50,60,60, fill='blue') ## this is just for visualisation, delete this line
me.zeichne(playarea)
dw.mainloop()

I only check the center of the player, normally you do check the "box" of the player.