Я предполагаю, что полученное вами сообщение об ошибке связано с тем, что вы не вызываете метод суперкласса '__init__()
в своем подклассе Thread
.
Найти так сложноошибка, когда в редакторе нет ошибок.
Вам необходимо научиться искусству отладки.
Не удалось правильно применить многопоточность.
Я думаю, что здесь есть две проблемы.Во-первых, чтобы использовать многопоточность с черепахой, которая построена поверх tkinter, вам нужно направить все графические команды через основной поток - вторичные потоки не должны пытаться изменить экран напрямую.
Во-вторых, ваш кодбеспорядок.Помимо многопоточности, не ясно, что вы понимаете объектное программирование, поскольку у вас есть два идентичных класса, за исключением координаты X.Это должен быть один класс с аргументом для его инициализатора.Не ясно, что вы берете черепаху, поскольку wn.onkeypress(paddle1.run(), "s")
никогда не будет работать.Вы, вероятно, не должны возиться с tracer()
и update()
, пока ваш код не заработает.И у вас не должно быть while True:
в главном потоке черепахи.
Я разобрал ваш код и собрал его вместе ниже.Отдельным потоком является только мяч, класс (одиночный) весла теперь наследуется от Turtle
.Основной поток обрабатывает графические команды из потока шара, а также стандартные события черепахи:
from turtle import Screen, Turtle
from threading import Thread, active_count
from queue import Queue
QUEUE_SIZE = 1
class Paddle(Turtle):
def __init__(self, xcor):
super().__init__(shape='square')
self.shapesize(stretch_wid=5, stretch_len=1)
self.speed('fastest')
self.penup()
self.setx(xcor)
self.dy = 10
def down(self):
y = self.ycor() - self.dy
if y > -250:
self.sety(y)
def up(self):
y = self.ycor() + self.dy
if y < 250:
self.sety(y)
class Ball(Thread):
def __init__(self):
super().__init__(daemon=True)
self.pen = Turtle('circle')
self.pen.speed('fastest')
self.pen.color('red')
self.pen.penup()
self.dx = 1
self.dy = 1
def run(self):
x, y = self.pen.position()
while True:
x += self.dx
y += self.dy
if x > 330 and (paddle2.ycor() - 60 < y < paddle2.ycor() + 60):
self.dx *= -1
elif x < -330 and (paddle1.ycor() - 60 < y < paddle1.ycor() + 60):
self.dx *= -1
if y > 290:
y = 290
self.dy *= -1
elif y < -290:
y = -290
self.dy *= -1
elif not -440 < x < 440:
x, y = 0, 0
self.dx *= -1
actions.put((self.pen.setposition, x, y))
def process_queue():
while not actions.empty():
action, *arguments = actions.get()
action(*arguments)
if active_count() > 1:
screen.ontimer(process_queue, 100)
screen = Screen()
screen.title("Ping pong rework by cdlane")
screen.bgcolor('blue')
screen.setup(width=900, height=600)
actions = Queue(QUEUE_SIZE)
paddle1 = Paddle(-350)
paddle2 = Paddle(350)
ball = Ball()
screen.onkeypress(paddle1.up, 'w')
screen.onkeypress(paddle1.down, 's')
screen.onkeypress(paddle2.up, 'Up')
screen.onkeypress(paddle2.down, 'Down')
screen.listen()
ball.start()
process_queue()
screen.mainloop()
Код все еще неполон и немного глючит (например, не закрывается чисто) - вещи для работына.Но он в основном играет в игру разумным образом.