Проблема в этой строке:
if is_collided_with(ball, ball):
Вы дважды передаете один и тот же объект ball
, обрабатывая его так, как если бы он разделял шары. В основном, для каждого шара в вашем списке шаров, оператор if говорит: "Этот шар сталкивается сам с собой?" - что всегда будет верно для каждого кадра симуляции. Поэтому вы всегда вводите тело оператора if и переворачиваете текущие векторы x- и y-шаров, что приводит к тому, что каждый шар просто колеблется на месте.
Наивное решение включает сравнение текущий шар со всеми другими шарами в симуляции. Я говорю «наивный», потому что, хотя это работает, оно становится ужасно неэффективным и медленным для большего количества шаров. Более сложное решение будет использовать некоторую технику разделения пространства, такую как квадродерево, чтобы значительно улучшить производительность (это работает только путем сравнения шаров, которые могут быть близко друг к другу, тогда как все другие шары, которые находятся далеко, отбраковываются и не рассматриваются для сравнение).
В вашем случае, пока количество шариков невелико, наивное решение должно работать нормально. Это выглядело бы примерно так (обратите внимание на вложенную форму -l oop):
while True:
wn.update()
for ball in balls:
ball.sety(ball.ycor() + ball.dy)
ball.setx(ball.xcor() + ball.dx)
for other_ball in balls:
if other_ball is ball:
# We are not interested in balls colliding with themselves.
# Skip the current iteration of the inner for-loop, and move on to the next ball
continue
if is_collided_with(ball, other_ball):
ball.dx *= -1
ball.dy *= -1
if ball.ycor() <-300:
ball.dy *=-1
if ball.ycor() >+300:
ball.dy *=-1
if ball.xcor() >+300:
ball.dx *=-1
if ball.xcor() <-300:
ball.dx *=-1
И еще одна вещь, имейте в виду, что технически то, что два шарика сталкиваются, не означает, что их направление - компоненты вектора (и x и y) должны быть / должны быть перевернуты. Представьте себе сценарий, в котором два шара движутся в одном и том же направлении, но с немного отличающимися скоростями, где мяч впереди медленнее, чем тот, который позади него (который догоняет) - если они столкнутся, было бы неправильно перевернуть оба направления. -векторные компоненты.