Обратный отсчет жизней в python turtle

#python #turtle-graphics

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

Вопрос:

Я пытаюсь создать простую игру python turtle, в которой черепаха должна добраться до круга, избегая при этом движущегося квадрата. Я бы хотел, чтобы код отсчитывал жизни и перемещал черепаху обратно в начало, пока не останется 0 жизней. Приведенный ниже код допускает одно воспроизведение, а затем цикл движения не повторяется.

Я пробовал рекурсивную функцию (move (3)), но тогда команды onkey не работают….

 import turtle, random, time

#background
canvas = turtle.Screen()
canvas.bgcolor('black')

#Pen
pen = turtle.Turtle()
pen.penup()
pen.color('white')
pen.hideturtle()
pen.penup()

#Lilypad
pad = turtle.Turtle()
pad.hideturtle()
pad.color('yellow')
pad.shape('circle')
pad.penup()
pad.setposition(0,290)
pad.showturtle()

#Turtle
player = turtle.Turtle()
player.hideturtle()
player.shape('turtle')
player.color('green')
player.penup()
player.left(90)
player.setposition(0, -290)
player.showturtle()

#truck
truck1 = turtle.Turtle()
truck1.hideturtle()
truck1.shape('square')
truck1.color('blue')
truck1.penup()
truck1.showturtle()

speed = random.randint(1,5)

def move():
  #move player and truck
  player.forward(2)
  truck1.forward(speed)
  if truck1.xcor() > 300 or truck1.xcor() < -300:
    truck1.right(180)

 #win if hit the lilypad
  if player.distance(pad)<10:
    pen.penup()
    pen.setposition(0,-50)
    pen.write('You win!', align='left', font=('Arial', 36, 'normal'))
    done()

  #lose a life if hit the truck
  if player.distance(truck1) < 30:
    player.setposition(0,-290)
    life = life - 1
    while life > 0:
      pen.penup()
      pen.setposition(0,-60)
      pen.write('Try again', align='left', font=('Arial', 36, 'normal'))
      time.sleep(1)
      pen.clear()
      move()

    #game over if 0 lives left
    pen.penup()
    pen.setposition(0,-60)
    pen.write('Game over!', align='left', font=('Arial', 36, 'normal'))
    done()

  canvas.ontimer(move,10)

canvas.onkey(lambda:player.setheading(90),'Up')
canvas.onkey(lambda:player.setheading(180),'Left')
canvas.onkey(lambda:player.setheading(0),'Right')
canvas.onkey(lambda:player.setheading(270),'Down')
canvas.listen()

life = 3
move()
canvas.mainloop()
  

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

1. чтобы повторить что-то, вы можете использовать цикл for или while

Ответ №1:

Ключом к этому является перемещение всего вашего кода инициализации в функцию, которая вызывает вашу move() функцию на последнем шаге. Первое, что делает код инициализации, — это вызов canvas.clear() , который в значительной степени уничтожает все. Затем ваша move() функция в конце делает выбор, вызывать ли себя на следующей итерации таймера или вызывать код инициализации на следующей итерации таймера, чтобы сбросить все и начать новую игру.

Ниже приведен ваш код, переработанный в соответствии с приведенными выше строками, а также различные тики:

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

FONT = ('Arial', 36, 'normal')

def initialize():
    global pen, pad, player, truck, speed, life

    canvas.clear()  # assume that this resets *everything*
    # background
    canvas.bgcolor('black')

    # Pen
    pen = Turtle(visible=False)
    pen.color('white')
    pen.penup()

    # Lilypad
    pad = Turtle('circle', visible=False)
    pad.color('yellow')
    pad.penup()
    pad.setposition(0, 290)
    pad.showturtle()

    # Turtle
    player = Turtle('turtle', visible=False)
    player.color('green')
    player.penup()
    player.setheading(90)
    player.setposition(0, -290)
    player.showturtle()

    # truck
    truck = Turtle('square', visible=False)
    truck.color('blue')
    truck.penup()
    truck.showturtle()

    speed = randint(1, 5)

    canvas.onkey(lambda: player.setheading(90), 'Up')
    canvas.onkey(lambda: player.setheading(180), 'Left')
    canvas.onkey(lambda: player.setheading(0), 'Right')
    canvas.onkey(lambda: player.setheading(270), 'Down')
    canvas.listen()

    life = 3

    move()

def move():
    global life

    # move player and truck
    player.forward(2)

    truck.forward(speed)
    if not -300 < truck.xcor() < 300:
        truck.right(180)

    # lose a life if hit the truck
    if player.distance(truck) < 20:
        player.setposition(0, -290)
        life -= 1

        if life > 0:
            pen.setposition(0, -60)
            pen.write('Try again', font=FONT)
            sleep(1)
            pen.clear()

    # win if hit the lilypad
    if player.distance(pad) < 20:
        pen.setposition(0, -50)
        pen.write('You win!', font=FONT)
        canvas.ontimer(initialize, 1000)
    elif life == 0:  # game over if 0 lives left
        pen.setposition(0, -60)
        pen.write('Game over!', font=FONT)
        canvas.ontimer(initialize, 1000)
    else:
        canvas.ontimer(move, 10)

canvas = Screen()

pen = None
pad = None
player = None
truck = None
speed = -1
life = -1

initialize()

canvas.mainloop()
  

Это должно позволить вам играть снова, независимо от того, выиграете вы или у вас закончатся жизни.