Erich Schmidt Erich Schmidt - 7 months ago 8
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

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.