1

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?

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.