Черепаха останавливается, когда я стреляю

#python #turtle-graphics

#python #черепаха-графика

Вопрос:

У меня возникла проблема, из-за которой вражеская черепаха останавливается, когда я стреляю. Я относительно новичок в Python, поэтому я знаю, что мой код довольно плох. Кажется, я не могу понять, почему это происходит, но я предполагаю, что это как-то связано с циклом while.

вот код: (я добавил примечания, чтобы было легко перейти к важным его частям)

 import turtle
import os
#wn is window
#bp = border
bullet = 'ready'
#screen setup
wn = turtle.Screen()
wn.bgcolor('black')
wn.title('SPACE.INVADERS')


#border
bp = turtle.Turtle()
bp.speed(0)
bp.color('green')
bp.penup()
bp.setposition(-300,-300)
bp.pendown()
count=0
while count != 5:
    count= (count 1)
    bp.fd(600)
    bp.lt(90)
bp.hideturtle()

#player
p = turtle.Turtle()
p.color('red')
p.shape('triangle')
p.penup()
p.speed(0)
p.setposition(0,-250)
p.setheading(90)

#enemy
e = turtle.Turtle()
e.penup()
e.speed(0)
e.shape('square')
e.shapesize(1.25,1.25)
e.color('orange')
e.setpos(-250,250)
e.speed(1)





#p = player
#ps = player speed

ps = 15

#moving left and right
def left_mov():
    x = p.xcor()
    x -= ps
    p.setx(x)

def right_mov():
    x = p.xcor()
    x  = ps
    p.setx(x)
#shooting
def shoot():
    global bullet
    if bullet == 'ready':
        bullet = 'fire'
        shot= turtle.Turtle()
        shot.penup()
        shot.speed(0)
        shot.goto(p.pos())
        shot.color('white')
        shot.shape('triangle')
        shot.shapesize(0.5)
        shot.lt(90)
        shot.speed(1)
        shot.fd(550)
        bullet = 'ready'




#bindings
turtle.listen()
turtle.onkey(left_mov, 'Left')
turtle.onkey(right_mov, 'Right')
turtle.onkey(shoot, 'space')
#enemy movement
while True:
    e.fd(500)
    e.rt(90)
    e.fd(25)
    e.rt(90)
    e.fd(500)
    e.lt(90)
    e.fd(25)
    e.lt(90)
  

Ответ №1:

Я предполагаю, что это как-то связано с циклом while

Да, этого не должно быть там! В мире, управляемом событиями, таком как turtle, никогда не должно быть while True: цикла. Вместо этого нам нужно событие таймера, которое запускается через регулярные промежутки времени и выполняет постепенные обновления движущихся объектов (врага и пули), чтобы казалось, что они движутся одновременно. Ниже приведена моя доработка вашего кода с использованием события таймера:

 from turtle import Screen, Turtle

# moving left and right
def left_move():
    player.setx(player.xcor() - player_speed)

def right_move():
    player.setx(player.xcor()   player_speed)

# screen setup
screen = Screen()
screen.bgcolor('black')
screen.title('SPACE.INVADERS')

# border
border = Turtle(visible=False)
border.speed('fastest')
border.color('green')

border.penup()
border.setposition(-300, -300)
border.pendown()

for _ in range(4):
    border.forward(600)
    border.left(90)

# player
player = Turtle('triangle')
player.speed('fastest')
player.color('red')

player.penup()
player.setposition(0, -250)
player.setheading(90)

player_speed = 15

# enemy
enemy = Turtle('square')
enemy.speed('fast')
enemy.shapesize(1.25)
enemy.color('orange')
enemy.penup()

enemy.setpos(-250, 250)

enemy_speed = 6  # enemy speed
enemy_direction = 1  # enemy direction

# bullet
bullet = Turtle('triangle', visible=False)
bullet.speed('fastest')
bullet.color('white')
bullet.shapesize(0.5)
bullet.penup()
bullet.left(90)

bullet_speed = 9  # bullet speed

# shooting

def shoot():
    if not bullet.isvisible():
        bullet.goto(player.position())
        bullet.showturtle()

def move():
    global enemy_direction

    if bullet.isvisible():
        if bullet.ycor() > 275:
            bullet.hideturtle()
        else:
            bullet.forward(bullet_speed)

    # enemy movement

    enemy.forward(enemy_direction * enemy_speed)
    enemy.settiltangle(enemy.tiltangle()   3)  # just for fun

    x, y = enemy.position()

    if x > 250 or x < -250:
        enemy_direction *= -1
        enemy.sety(y - 25)

    screen.ontimer(move, 50)

# bindings
screen.onkey(left_move, 'Left')
screen.onkey(right_move, 'Right')
screen.onkey(shoot, 'space')
screen.listen()

move()

screen.mainloop()
  

Это должно дать вам базовую функциональность, необходимую для продвижения вперед и добавления обнаружения столкновений (пуля во врага, враг в игрока, игрок в стену) и подсчета очков.

Также обратите внимание, что turtles являются глобальными объектами, поэтому создавать новый маркер каждый раз, когда он вам нужен, — плохая идея. Даже если вы обычно разрешаете перекрывающиеся маркеры, сохраните для этой цели набор маркеров многократного использования.