Я пытаюсь выполнить обнаружение столкновений среди членов списка черепах, чтобы переменная возвращала логическое значение, чтобы разорвать цикл while true. Это работает с ОДНОЙ из черепах, но не с остальными. Он также печатает расстояние (для отладки) только для того, с которым работает столкновение. Что сбивает с толку, так это то, что тот же синтаксис, который используется в функции столкновения, отлично работает в циклах обнаружения столкновений шара и стены.
import turtle
from turtle import Screen
import random
from random import randrange
screen = turtle.Screen()
screen.setup(500, 500)
screen.title('Balls Bounce')
friend = turtle.Turtle()
friend.shape('turtle')
friend.color('green')
friend.turtlesize(3)
def friendUp():
friend.setheading(90)
friend.forward(45)
def friendDown():
friend.setheading(270)
friend.forward(45)
def friendRight():
friend.setheading(0)
friend.forward(45)
def friendLeft():
friend.setheading(180)
friend.forward(45)
screen.onkey(friendUp, "Up")
screen.onkey(friendLeft, "Left")
screen.onkey(friendRight, "Right")
screen.onkey(friendDown, "Down")
screen.listen()
def createBall():
ball = turtle.Turtle(shape = "circle")
ball.penup()
ball.color("Red")
ball.turtlesize(3)
ball.setheading(randrange(361))
ball.forward(5)
return ball
balls = []
for i in range(5):
b = createBall()
balls.append(b)
bodySize = 80
halfBodySize = bodySize / 2
collisionDistance = 5
isCollision = False
def collision(balls, friend):
distance = 0
for b in balls:
distance = b.distance(friend)
print(distance // 1)
if distance < halfBodySize:
print('Collision!')
global isCollision
isCollision = True
break
return isCollision
while True:
collision(balls, friend)
if isCollision == True:
break
for b in balls:
b.forward(5)
xPos = b.position()[0]
yPos = b.position()[1]
if xPos > 250 or xPos < -250:
b.forward(-5)
b.setheading(randrange(361))
if yPos > 250 or yPos < -250:
b.forward(-5)
b.setheading(randrange(361))
screen.mainloop()
Я пробовал использовать карту и перечисление, но они продолжают возвращать проблемы, которые я не могу понять. Например, использование enumerate возвращает проблемы с кортежами, и я не уверен, что правильно настроил для него синтаксис. Карта имеет аналогичные проблемы.
Пожалуйста, внимательно подумайте над логикой. Когда должно произойти return isCollision: после того, как цикл завершил проверку шаров, или в конце каждого прохода цикла? Следовательно, должен ли этот код находиться внутри цикла или снаружи? Это там, где должно быть?
Или посмотрите на это по-другому: у вас есть список balls, и вы хотите знать, верно ли для любого из них утверждение «этот мяч сталкивается с игроком» — да? Итак, у этого есть много стандартных решений, и его достаточно легко исследовать (для этого я добавил отдельную дублирующую ссылку). Похоже, вам не повезло допустить ошибку в каждом из нескольких подходов. Но большая часть проблемы заключается в вашем общем понимании. Если вы описываете это как «использование перечисляемых возвращаемых кортежей», тогда вам необходимо изучить, что означают эти слова, как работают инструменты и как понимать ошибки.
(Аналогично: неправильный синтаксис может вызвать только SyntaxError или какой-либо его подтип, например IndentationError или TabError. Если вы получаете неправильный результат, это либо из-за неправильной логики, либо просто из-за непонимания того, как работает конкретный инструмент.)






return isCollision необходимо сделать на один уровень дальше, внутри if, который обнаруживает столкновение:
def collision(balls, friend):
for b in balls:
distance = b.distance(friend)
print(distance // 1)
if distance < halfBodySize:
print('Collision!')
return True
return False
Если он находится за пределами if, он всегда будет возвращать результат первого столкновения мяча с другом и никогда не пройдет первую итерацию цикла.
Нет необходимости в global — просто верните значение и используйте его непосредственно в вызывающем коде:
if collision(balls, friend):
# there was a collision between a ball and friend
Вы также можете удалить свои вызовы print(), после чего рассмотрите возможность использования any:
def collision(balls, friend):
return any(b.distance(friend) < halfBodySize for b in balls)
Вот минимальное доказательство правильности:
from random import randint
from turtle import Screen, Turtle
def check_collision(ball, balls):
return any(b.distance(ball) < HALF_BODY_SIZE for b in balls)
def reposition():
for t in turtles:
t.goto(randint(-w, w), randint(-h, h))
friend.color("green")
if check_collision(friend, balls):
friend.color("red")
screen.update()
HALF_BODY_SIZE = 60
screen = Screen()
w, h = screen.screensize()
screen.tracer(0)
turtles = []
for _ in range(35):
t = Turtle(shape = "circle")
turtles.append(t)
t.shapesize(3)
t.penup()
friend, balls = turtles[-1], turtles[:-1]
reposition()
screen.onclick(lambda *_: reposition())
screen.mainloop()
Кроме того, используйте snake_case для функций и переменных, а не camelCase, согласно соглашению PEP-8.
Также предпочитайте from turtle import Screen, Turtle, чтобы не путать функциональные и ООП-интерфейсы. Ваш текущий код никогда не использует from turtle import Screen, который можно поймать с помощью линтера, такого как Flake 8.
Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой и указать достаточно подробностей, чтобы найти адекватный ответ.