Почему мои функции работают миллион миль в час? - PullRequest
0 голосов
/ 22 марта 2020

Функции врага1, врага2 и врага3 должны запускаться мгновенно, используя функцию ontimer, перемещая черепах внутри них, одновременно выполняя вложенную функцию checkcollision, чтобы проверить, сталкиваются ли черепахи с пользователем. Наряду с этим запускается функция вложенной контрольной пули для проверки расстояния, чтобы увидеть, сталкиваются ли они с черепахой пули, и функция вложенной проверки земли, чтобы проверить их расстояние от черепа земли, которая является синим кружком в правом нижнем углу экрана. Однако эти 3 функции работают на гиперсони c скорости, и я не могу понять, почему.

from turtle import Screen, Turtle
import random
from random import randint

#screen setup
screen = Screen()
screen.setup(width=450, height=450)
screen.bgcolor('black')
screen.tracer(3)
#user
player = Turtle()
player.shape('square')
player.color("green")
player.penup()
#First enemy
player2 = Turtle()
player2.color("green")
player2.shape('turtle')
player2.penup()
player2.setpos(random.randint(-200,200), random.randint(-200,200))
player2.setheading(random.randint(1,360))
#Second enemy
player3 = Turtle()
player3.color("green")
player3.shape('square')
player3.penup()
player3.setpos(random.randint(-200,200), random.randint(-200,200))
player3.setheading(random.randint(1,360))
#third enemy
player4 = Turtle()
player4.color("green")
player4.shape('triangle')
player4.penup()
player4.setpos(random.randint(-200,200), random.randint(-200,200))
player4.setheading(random.randint(1,360))

#earth

earth = Turtle()
earth.penup()
earth.shape("circle")
earth.color("blue")
earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6)
earth.setpos(150,-150)

#bullet
bullet = Turtle()
bullet.shape("turtle")
bullet.color("purple")
bullet.hideturtle()
bullet.penup()
bullet.setpos(random.randint(-200,200),random.randint(-200,200))
bullet.hideturtle()
bullet.penup()
px = 0
py = 0

def up():
    global px
    global py
    py = player.ycor() + 5

    if py >= 200:
        py -= 15

    player.sety(py)

def down():
    global px
    global py
    py = player.ycor() - 5

    if py < -200:
        py += 15

    player.sety(py)

def left():
    global px
    global py
    px = player.xcor() - 5

    if px <= -200:
        px += 15

    player.setx(px)

def right():
    global px
    global py
    px = player.xcor() + 5

    if px >= 200:
        px -= 15 

    player.setx(px)




#distance calculator
def checkcollision(t1, t2):
    while t1.distance(t2) < 10:
        t2.setpos(randint(-100, 100), randint(-100, 100))

# the x and y distance that the player2 turtle moves 
dx = 5
dy = 5

damage = 0

def checkbullet(bullet,turtle):
    while bullet.distance(turtle) < 10:
        turtle.hideturtle()

def check_earth(planet,turtle):
    global damage
    damage+=1
    while planet.distance(turtle)>10:
        turtle.setpos(random.randint(-200,200),random.randint(-200,200))

#1st enemy(switch heading)
head = 0
def enemy1():
    checkcollision(player,player2)
    check_earth(earth,player2)
    global head
    player2.fd(5)

    x2, y2 = player2.position()
    head = player2.heading()

    if y2 <= -200 or y2 >= 200:
        player2.fd(0)
        player2.backward(7.5)
        player2.setheading((head)* -1)

    if x2 <= -200 or x2 >= 200:
        player2.fd(0)
        player2.backward(7.5)
        if head < 90:
            player2.setheading(0 - ((head) * 2))
        if head>90<179:

            player2.setheading((head)/2)

        if head>179<260:
            player2.setheading((head)/3)


        if head>260<361:
            player2.setheading((head)/2)

    screen.ontimer(enemy1,50)

#Second enemy(dx,dy)
def enemy2():
    checkcollision(player, player3)
    check_earth(earth,player3)


    global dx
    global dy
    x3, y3 = player3.position()

    player3.setposition(x3 + dx, y3 + dy)


    if y3 <= -200 or y3 >= 200:
        dy *= -1
        player3.sety(y3 + dy)

    if x3 <= -200 or x3 >= 200:
        dx *= -1
        player3.setx(x3 + dx)


    screen.ontimer(enemy2,50)

def enemy3():
    checkcollision(player,player4)
    check_earth(earth,player4)

    player4.fd(5)
    x4, y4 = player4.position()
    head3 = player4.heading()

    if y4 <= -200 or y4 >= 200:
        player4.fd(0)
        player4.backward(7.5)
        player4.fd(0)
        player4.setheading((head3)* -1)

    if x4 <= -200 or x4 >= 200:
        player4.fd(0)
        player4.backward(7.5)
        player4.fd(0)
        if head3 < 90:
            player4.setheading(0 - ((head3) * 2))
        if head3>90<179:
            player4.setheading((head3)/2)

        if head3>179<260:
            player4.setheading((head3)/3)


        if head3>260<361:
            player4.setheading((head3)/2)
    screen.ontimer(enemy3,50)

#When bullet hits wall   
def bullet_end():
    screen.listen()   
    screen.onkeypress(up, 'Up')
    screen.onkeypress(left, 'Left')
    screen.onkeypress(right, 'Right')
    screen.onkeypress(down, 'Down')
    screen.onkeyrelease(shoot_key,"w")


def shoot_key():


    bullet.setposition(px,py)
    bullet.shape("circle")
    bullet.showturtle()
    bullet.penup()

    def shoot():
        checkbullet(bullet,player2)
        checkbullet(bullet,player3)
        checkbullet(bullet,player4)
        bx = bullet.xcor()
        by = bullet.ycor()
        bullet.fd(5)
        if bx>=200 or bx<=-200:
            bullet.hideturtle()
            bullet.backward(7.5)
            bullet_end()
        if by>=200 or by<=-200:
            bullet.hideturtle()
            bullet.backward(7.5)
            bullet_end()

        screen.ontimer(shoot,50)
    shoot()
screen.listen() 
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")



enemy1()
enemy2()
enemy3()
screen.mainloop()

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Не: пока pl anet .distance (черепаха)> 10: Да: пока pl anet .distance (черепаха) <10: Решение было простым, и мы оба упустили его из виду, иногда я задаю немые вопросы. В любом случае спасибо за помощь </p>

0 голосов
/ 22 марта 2020

Проблема вызвана функцией check_earth. Насколько я вижу, вы пытаетесь не допустить, чтобы противник был слишком близко к земле - если он туда попадет, он должен получить новую, случайную позицию. Очевидно, что эта новая позиция также не должна быть слишком близко к земле, так что вы делаете это в 1019 *. Однако в l oop.

есть три ошибки. Во-первых, условие для поиска новой позиции: while planet.distance(turtle)>10: всегда выполняется для действительного места.

Во-вторых, вы Немедленно перемещайте противника в новую случайную позицию, не проверяя условия, что создает много трафика c. Вместо этого вам следует устанавливать позицию только тогда, когда вы уверены, что она правильная.

Наконец, откуда взялась величина '10'? Чтобы объявить размер вашего круга, вы использовали: earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6). Существует следующая зависимость между радиусом земли и длиной растяжения: 2*RADIUS/CURSOR_SIZE. Поскольку значение CURSOR_SIZE по умолчанию равно 20, это будет означать, что радиус вашего круга равен 56. Если мы хотим обнаружить столкновение, как только какая-либо часть вражеской черепахи коснется земли, мы также должны добавить длину вражеского курсора.

Итак, вместо:

def check_earth(planet,turtle):
    global damage
    damage+=1
    while planet.distance(turtle)>10:
        turtle.setpos(random.randint(-200,200),random.randint(-200,200))

Вы должны определить функцию check_earth как:

CURSOR_SIZE = 20
EARTH_RADIUS = 56
def check_earth(planet,turtle):
    global damage
    damage+=1

    (turtle_x, turtle_y) = turtle.pos()
    while True:
        if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
            turtle.setpos(turtle_x,turtle_y)
            break

        turtle_x = random.randint(-200,200)
        turtle_y = random.randint(-200,200)
...