Python tkinter - Перемещение объекта в Canvas - PullRequest
0 голосов
/ 14 ноября 2018

Я только изучаю Python, и я хотел создать маленькую маленькую игру, где я мог бы перемещать объект влево, вправо, вверх и вниз ...

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)

Я только что запрограммировалдвижущаяся правая часть, однако у меня возникла проблема, она не видит, что a равно 400, но если я запишу его в def, то смогу переместить его только один раз в новую позицию, тогда он остановится там ..... любое решениеза это?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Чтобы решить проблему с movenent, вам нужно использовать оператор global, чтобы функция знала, что переменные, с которыми вы пытаетесь работать, находятся в глобальном пространстве имен.

При этом я бы выступил за подход ООП, чтобы избежать использования глобальных.

Встраивая это в класс и используя атрибуты класса, мы можем управлять движением без глобальных изменений. Кроме того, если мы работаем с событием, передаваемым в наш метод класса, мы можем использовать один метод для перемещения во всех 4 направлениях.

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()
0 голосов
/ 14 ноября 2018

Когда вы изменяете a и b в moveright, оно становится локальным, поэтому при следующем вызове moveright a и b больше не существуют.

Без моего повторного вызова- написав большую часть своего кода, вы могли бы сделать простое исправление, объявив a и b глобальными в moveright, чтобы они сохранялись после завершения moveright:

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)

, поскольку a и b теперь глобальные, они сохраняются после завершения moveright и могут использоваться при следующем вызове moveright.

Примечание: это не лучший способ, которым ваша программа могла бы бытьнаписано, просто самое простое исправление, которое также устраняет причину проблемы.

...