Python-turtle: из математической библиотеки: dist () вызывает выход из цикла / замораживание

#python #python-turtle

#python #python-turtle

Вопрос:

Я пытаюсь создать игру с использованием Python (с turtle) цель игры — застрелить другого человека

Проблема связана с кодом столкновения. Я проверяю столкновения с использованием маркеров dist() , но, похоже, это приводит к выходу / зависанию цикла (я действительно не знаю, какой).

Я пытался использовать формулу расстояния вместо функции, но это ничего не изменило

Вот мой код:

         bullet.forward(10)
        distancetop1 = dist(player1.pos(),bullet.pos())
        if self != player1 and distancetop1 < 2:
            bullet.clear()
            print("orange won!")
            exit()
        distancetop2 = dist(player1.pos(),bullet.pos())
        if self != player2 and distancetop2 < 2:
            bullet.clear()
            print("blue won!")
            exit()
  

Мой полный код, если необходимо, здесь

Ответ №1:

С помощью turtle не помещайте проверки ключей в цикл. Установите их один раз, затем вызовите listen . Используется mainloop для продолжения работы игры.

Попробуйте этот код:

 import turtle,random, math

sc = turtle.Screen()
sc.bgcolor("#000")

player1 = turtle.Turtle()
player1.color("#00f")
player1.speed(0)
player1.up()
player1.goto(-256,0)

player2 = turtle.Turtle()
player2.color("#ffa500")
player2.speed(0)
player2.up()
player2.goto(256,0)
player2.seth(180)

bullet1 = turtle.Turtle()
bullet1.color("#fff")
bullet1.speed(0)
bullet1.ht()
bullet1.up()
bullet1.active = False 

def dist(c1,c2):
   return math.sqrt((c1[0]-c2[0])**2   (c1[1]-c2[1])**2)

def shoot(self):
    bullet = bullet1.clone()
    bullet.active = True
    bullet.goto(self.xcor(),self.ycor())
    bullet.down()
    bullet.seth(self.heading())
    while (bullet.xcor() < 600 and bullet.xcor() > -600) and (bullet.ycor() < 256 and bullet.ycor() > -256):
        bullet.forward(10)
        distancetop1 = dist(player1.pos(),bullet.pos())
        if self != player1 and distancetop1 < 5:
            bullet.clear()
            print("orange won!")
            exit()
        distancetop2 = dist(player2.pos(),bullet.pos())
        if self != player2 and distancetop2 < 5:
            bullet.clear()
            print("blue won!")
            exit()
    bullet.clear()
def p1right():
    player1.seth(0)
    player1.forward(4)
def p1left():
    player1.seth(180)
    player1.forward(4)
def p1up():
    player1.seth(90)
    player1.forward(4)
def p1down():
    player1.seth(270)
    player1.forward(4)
def p1shoot():
    shoot(player1)

def p2right():
    player2.seth(0)
    player2.forward(4)
def p2left():
    player2.seth(180)
    player2.forward(4)
def p2up():
    player2.seth(90)
    player2.forward(4)
def p2down():
    player2.seth(270)
    player2.forward(4)
def p2shoot():
    shoot(player2)

#while True:
sc.onkey(p1right,"D")
sc.onkey(p1left,"A")
sc.onkey(p1up,"W")
sc.onkey(p1down,"S")
sc.onkey(p1shoot,"space")

sc.onkey(p2right,"Right")
sc.onkey(p2left,"Left")
sc.onkey(p2up,"Up")
sc.onkey(p2down,"Down")
sc.onkey(p2shoot,"Return")
sc.listen()
sc.mainloop()
  

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

1. хотя это, похоже, также работает вместо while, это не устраняет проблему остановки цикла пули при первой функции dist( ) .

2. Ответ обновлен. dist Метод доступен только в python 3.8. Мне пришлось написать пользовательскую dist функцию для тестирования.

3. Потрясающе, что работает безупречно, есть ли способ заставить mainloop / onkey останавливаться, когда кто-то попадает? спасибо и хорошего дня!

4. Если вы хотите, чтобы игра продолжалась, используйте return вместо exit()

5. Я хотел, чтобы игра полностью останавливалась, когда кого-то бьют. Однако я заменил exit() на return .