W moim prostym kodzie czerwona piłka spada w linii prostej (która działa). Po naciśnięciu klucza strzałki w prawo, chcę, aby piłka poruszała się również w odpowiednim kierunku. Nie działa jednak. Co ja robię źle?

from tkinter import *

root = Tk()

canvas = Canvas(root, height=400, width=500, background='black')
canvas.pack()


class Bird:
    def __init__(self, canvas, coords):
        self.canvas = canvas
        self.coords = coords
        self.bird = canvas.create_rectangle(coords, fill='red')

    def gravity(self):
        self.canvas.move(self.bird, 0, 10)
        self.canvas.after(200, self.gravity)

    def moveRight(self, event):
        self.canvas.move(self.bird, 10, 0)
        self.canvas.after(200, self.moveRight)

bird = Bird(canvas, (100, 100, 110, 110))

bird.gravity()

canvas.bind('<Right>', bird.moveRight)

root.mainloop()

Mam kolejne dodatkowe pytanie:

Czy można zadzwonić do tego "po" -Function lub podobnej funkcji dla całego płótna zamiast dwóch metod oddzielnie?

Jeśli widzisz jakieś inne wady z moim kodem Plz, daj mi znać!

Dzięki!

2
Kubi 28 wrzesień 2017, 08:38

2 odpowiedzi

Najlepsza odpowiedź

Musisz wiązać właściwy klucz do płótna wewnątrz klasy i ustaw ostrość na płótnie:

from tkinter import *

root = Tk()

canvas = Canvas(root, height=400, width=500, background='black')
canvas.pack()


class Bird:
    def __init__(self, canvas, coords):
        self.canvas = canvas
        self.coords = coords
        self.bird = canvas.create_rectangle(coords, fill='red')
        self.canvas.bind('<Right>', self.moveRight)
        self.canvas.focus_set()

    def gravity(self):
        self.canvas.move(self.bird, 0, 10)
        self.canvas.after(200, self.gravity)

    def moveRight(self, event=None):
        self.canvas.move(self.bird, 10, 0)
        self.canvas.after(200, self.moveRight)


bird = Bird(canvas, (100, 100, 110, 110))

bird.gravity()

root.mainloop()
1
Reblochon Masque 28 wrzesień 2017, 05:59

Problem, z którym stoisz, jest to, że jesteś wiążącym zdarzeniami klawiaturowymi, ale zdarzenia mogą działać tylko wtedy, gdy widżet z wiązaniami ma ustawianie ostrości klawiatury. Możesz dać na płótnie skupić się na klawiaturze za pomocą focus_set():

canvas = Canvas(root, height=400, width=500, background='black')
canvas.focus_set()

Czy można zadzwonić do tego "po" -Function lub podobnej funkcji dla całego płótna zamiast dwóch metod oddzielnie?

Tak. Twoje wiązanie może wywołać żądaną funkcję. Jeśli spodziewasz się mieć więcej niż jednego obiektu i chcesz, aby wszyscy poruszali się w tym samym czasie, możesz je przenieść wszystkie z funkcji.

Najpierw wyjmij połączenie do after z moveRight. Następnie zdefiniuj funkcję globalną, która wywołuje moveRight dla każdego obiektu. Na przykład:

def move_them_all():
    bird1.moveRight()
    bird2.moveRight()
    something_else.moveRight()
    self.canvas.after(1000, move_them_all)
...
canvas = Canvas(root, height=400, width=500, background='black')
...
canvas.bind('<right>', move_them_all)
0
Bryan Oakley 28 wrzesień 2017, 14:50