Функция перемещения объекта не имеет эффекта даже после вызова: Tkinter

#python #function #tkinter #canvas

#python #функция #tkinter #холст

Вопрос:

Итак, да, я новичок в играх Tkinter Canvas, и мне слишком сложно кодировать, чем я думал. Окк, давайте перейдем к делу, ниже приведен мой код:

 import time
from tkinter import *
from numpy import random
class Paddle:
    def __init__(self, Main_Frame):
        Main_Frame.title("Paddle")
        Main_Frame.geometry("300x300 630 150")
        self.Random_X = random.randint(270)
        self.Random_Y = random.randint(120)
        self.x = 3
        self.y = 3
        self.Y_Position = 288
        self.Can = Canvas(Main_Frame, height = 300, width = 300)
        self.Can.pack()
        self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill = "Aqua", outline = "Aqua")
        self.ball = self.Can.create_oval(self.Random_X, self.Random_Y, self.Random_X   20, self.Random_Y   20, outline = "Red", fill = "Red")
        self.Can.bind("<Motion>", self.Move_Paddle)
        self.Move_Ball()
    def Move_Ball(self):
        Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
        if Ball_x2 > 300:
            self.x = -self.x
        if Ball_y2 > 300:
            self.y = -self.y
        if Ball_x1 < 0:
            self.x = -self.x
        if Ball_y2 < 10:
            self.y = -self.y
        self.Can.moveto(self.ball, self.x, self.y)
        Window.after(1, self.Move_Ball)
    def Move_Paddle(self, event):
        self.X_Position = event.x
        self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)
Window = Tk()
Class = Paddle(Window)
Window.mainloop()
 

Итак, моя проблема здесь в том, что даже после вызова Move_Ball() функции это никак не повлияло на шар (okk, хотя ошибок не возникает), когда я попытался вызвать функцию в разделе Move_Paddle() function (перед добавлением Window.after(1, self.Move_Ball) строки), она работала хорошо, когда я перемещал мышь по холсту, ну, Я хочу, чтобы он автоматически активировался при Paddle вызове класса.
Я пытался проверить проблему в коде, поместив вызов функции в Move_Paddel() (со Window.after(1, self.Move_Ball) строкой, как в коде), это увеличило проблему и безумно увеличило скорость мяча.
Если кто-нибудь может помочь мне с этими двумя проблемами, это было бы высоко оценено.
Заранее спасибо!

Ответ №1:

Используйте move() вместо moveto() метода. move() метод перемещает каждый из элементов, заданных tagOrId в пространстве координат canvas, добавляя значение X к координате x каждой точки, связанной с элементом, и значение y к координате y каждой точки, связанной с элементом.

Тогда вы можете увеличить задержку в after() методе.

Вот рабочий код:

 import time
from tkinter import *
from numpy import random
class Paddle:
    def __init__(self, Main_Frame):
        Main_Frame.title("Paddle")
        Main_Frame.geometry("300x300 630 150")
        self.Random_X = random.randint(270)
        self.Random_Y = random.randint(120)
        self.x = 3
        self.y = 3
        self.Y_Position = 288
        self.Can = Canvas(Main_Frame, height = 300, width = 300)
        self.Can.pack()
        self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill = "Aqua", outline = "Aqua")
        self.ball = self.Can.create_oval(self.Random_X, self.Random_Y, self.Random_X   20, self.Random_Y   20, outline = "Red", fill = "Red")
        self.Can.bind("<Motion>", self.Move_Paddle)
        self.Move_Ball()

    def Move_Ball(self):
        Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
        
        
        if Ball_x2 > 300:
            self.x = -self.x

        if Ball_y2 > 300:
            self.y = -self.y

        if Ball_x1 < 0:
            self.x = -self.x

        if Ball_y2 < 10:
            self.y = -self.y

        self.Can.move(self.ball, self.x, self.y)

        Window.after(50 ,self.Move_Ball)

    def Move_Paddle(self, event):
        self.X_Position = event.x
        self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)
Window = Tk()
Class = Paddle(Window)
Window.mainloop()
 

Ответ №2:

Я переписал ваш код и теперь думаю, что он работает так, как вы хотели. Красный шар медленно опускается:

 import time
from tkinter import *
from numpy import random


class Paddle:
    def __init__(self, main_frame):
        self.root = main_frame
        random.seed(int(time.time()))
        self.x = random.randint(270)
        self.y = random.randint(120)
        self.Y_Position = 288
        self.Can = Canvas(self.root, height=300, width=300)
        self.Can.pack()
        self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill="Aqua", outline="Aqua")
        self.ball = self.Can.create_oval(self.x, self.y, self.x   20, self.y   20, outline="Red", fill="Red")
        self.Can.bind("<Motion>", self.move_paddle)
        self.move_ball()

    def move_ball(self):
        Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
        # if Ball_x2 > 300:
        #     self.x = -self.x
        # if Ball_y2 > 300:
        #     self.y = -self.y
        # if Ball_x2 < 0:
        #     self.x = 300
        if Ball_y2 > 300:
            self.y = 0
        self.y  = 0.1
        self.Can.moveto(self.ball, self.x, self.y)
        self.root.after(1, self.move_ball)

    def move_paddle(self, event):
        self.X_Position = event.x
        self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)


root = Tk()
root.title("Paddle")
root.geometry("300x300 630 150")
Class = Paddle(root)
root.mainloop()
 

И, пожалуйста, прочтите о PEP8

Ответ №3:

Вы должны использовать move() вместо moveto() inside Move_Ball() и after(1, ...) слишком часто, поэтому мяч будет перемещаться очень быстро. Попробуйте after(50, ...) вместо этого:

 def Move_Ball(self):
    ...
    self.Can.move(self.ball, self.x, self.y)
    Window.after(50, self.Move_Ball)
 

Комментарии:

1. Окк, спасибо, на самом деле я исправил эту вещь сразу после публикации вопроса, но это не сработало. Но я попробую второе решение.