简体   繁体   中英

Python tkinter - Moving object in Canvas

I'm just learning python and I wanted to create a small little game, where I can move an object to the left to the right, up and down...

import tkinter
canvas=tkinter.Canvas(width=800,height=600)
canvas.pack()

canvas.create_text(400,200,text='Starlight',font='Arial 100 bold')
canvas.create_text(400,325,text='Press a button to start the game',font='Arial 20')

a=400
b=500


def start(coordinates):
    canvas.delete("all")
    canvas.create_rectangle(a-20,b,a+20,b-50)

def moveright(coordinates2):
    a=a+100
    b=b+0
    canvas.delete("all")
    canvas.create_rectangle(a-20,b,a+20,b-50)




canvas.bind('<Button-1>',start)
canvas.bind('<Button-3>',start)
canvas.bind_all('<Right>',moveright)

I just programmed the moving right part, however I got a problem, it doesnt sees that a is 400, but if i write it into the def then I can move it just once to the new position, then it stops there.....any solution for this?

When you change a and b in moveright , it becomes local, so the next time moveright is called, a and b don't exist anymore.

Without my re-writing a lot of your code, you could make a simple fix by declaring a and b as global in moveright , so they persist after moveright terminates:

def moveright(coordinates2):
    global a
    global b
    a=a+100
    b=b+0
    canvas.delete("all")
    canvas.create_rectangle(a-20,b,a+20,b-50)

Since a and b are now global, they persist after moveright terminates, and can be used by the next call to moveright .

Note: This isn't the best way your program could be written, just the simplest fix that also obviates the cause of the problem.

In order to fix your issue with movenent you will need to use the global statement to let the function know the variables you are trying to work with are in the global namespace.

That said I would advocate for an OOP approach to avoid the use of global.

By building this into a class and using class attributes we can manage the movement without global. Additionally if we work with the event being passed to out class method we can use a single method to move in all 4 directions.

import tkinter as tk


class Example(tk.Tk):
    def __init__(self):
        super().__init__()

        self.canvas=tk.Canvas(self, width=800, height=600)
        self.canvas.create_text(400, 200, text='Starlight', font='Arial 20 bold')
        self.canvas.create_text(400, 325, text='Press a button to start the game', font='Arial 20')
        self.canvas.pack()
        self.a=400
        self.b=500
        self.canvas.bind('<Button-1>', self.start)
        self.canvas.bind('<Button-3>', self.start)
        self.canvas.bind_all('<Left>', self.move_any)
        self.canvas.bind_all('<Right>', self.move_any)
        self.canvas.bind_all('<Up>', self.move_any)
        self.canvas.bind_all('<Down>', self.move_any)

    def start(self, coordinates):
        self.canvas.delete("all")
        self.canvas.create_rectangle(self.a - 20, self.b, self.a + 20, self.b - 50)

    def move_any(self, event):
        self.canvas.delete("all")
        x = event.keysym
        if x == "Left":
            self.a -= 100
        if x == "Right":
            self.a += 100
        if x == "Up":
            self.b -= 100
        if x == "Down":
            self.b += 100 
        self.canvas.create_rectangle(self.a - 20, self.b, self.a + 20, self.b - 50)

if __name__ == "__main__":
    Example().mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM