Python Turtle: запуск обратного отсчета зависает

Я делаю игру с уклонением, в которой черепаха (в форме черепахи) должна избегать других черепах (в форме крокодилов). У меня работает игра, но я пытаюсь добавить обратный отсчет до начала игры, который идет 3, 2, 1, GO!

Я думаю, что, поскольку переменная countdown_number, которая у меня есть, принимает значения 3, 2, 1, а затем ВПЕРЕД!, я могу сделать так, чтобы она появлялась раньше остальной части игры, если все остальное зависит от значения countdown_number, равного «ВПЕРЕД!» .

Однако прямо сейчас, когда я запускаю программу, она зависает на 3, и после интервала обновления начинается снова, вместо того, чтобы продолжать через 2, 1 и ВПЕРЕД! поэтому игра не может запуститься.

Я видел много вопросов о переполнении стека, которые связаны с запуском таймеров и вещами, параллельными игре, но мне нужно, чтобы это произошло до начала игры.

import turtle
import random
import pygame

window_height = 600
window_width = 600

update_interval = 25

countdown_number = 3

river_width = 400
minimum_river_width = 200

border_height = 600

river_width_update = 0.5

safe_distance_from_border = border_height / 2 + 3

number_of_enemies = 10
enemies = []
enemy_speeds = []
enemy_width = 100
enemy_height = 40
enemy_speed_min, enemy_speed_max = 10, 20

safe_distance_from_enemy = 15

def startgame():
    global countdown_number
    if countdown_number >= 1:
        turtle.home()
        turtle.left(270)
        turtle.clear()
        turtle.speed(0)
        for _ in range(0,100,5):
            turtle.forward(1)
            turtle.color("grey"+str(_))
            turtle.write(countdown_number, align="center", font=("Arial", 200, "normal"))
    if countdown_number == 0:
        countdown_number = "GO!"
        turtle.home()
        turtle.left(270)
        turtle.clear()
        turtle.speed(0)
        for _ in range(0,100,5):
            turtle.forward(1)
            turtle.color("grey"+str(_))
            turtle.write(countdown_number, align="center", font=("Arial", 200, "normal"))
        turtle.clear()

    #print(number)

def gameover(msg):
    print(msg) # Probably comment this out later
    turtle.home()
    turtle.write(msg, align="center", font=("Arial", 24, "normal"))

def moveplayerturtle(x, y):
    if x > -window_width / 2 and x < window_width / 2:
        turtle.goto(x, y)

def updatescreen():

    global river_width
    global countdown_number
    if countdown_number != "GO!":
        startgame()

    if countdown_number == "GO!":

        if upper_river_border.ycor() >= window_height-200:
            upper_river_border.sety(upper_river_border.ycor() - river_width_update)

        if lower_river_border.ycor() <= -window_height+200:
            lower_river_border.sety(lower_river_border.ycor() + river_width_update)

        if upper_river_border.ycor() - turtle.ycor() < safe_distance_from_border:

            gameover("Game over!")

            return
        if turtle.ycor() - lower_river_border.ycor() < safe_distance_from_border:

            gameover("Game over!")

            return

        for i in range(number_of_enemies):

            enemies[i].forward(enemy_speeds[i])

            if enemies[i].xcor() > (window_width+enemy_width)/2:
                x = -(window_width+enemy_width)/2
                y = int(turtle.ycor())
                enemies[i].goto(x, y)
                s=1
                enemy_speeds[i]=int(random.randrange(10+s, 20+s))

            if turtle.distance(enemies[i]) < safe_distance_from_enemy:
                gameover("You lose!")
                return

    turtle.ontimer(updatescreen, update_interval)
    turtle.update()

turtle.setup(window_width, window_height) # Set the window size
turtle.bgcolor("DarkBlue")

turtle.tracer(False)

upper_river_border = turtle.Turtle()
upper_river_border.up()
lower_river_border = turtle.Turtle()
lower_river_border.up()

upper_river_border.shape("square")
lower_river_border.shape("square")

upper_river_border.color("DarkOrange4")
lower_river_border.color("DarkOrange4")

upper_river_border.shapesize(30, 40)
lower_river_border.shapesize(30, 40)

upper_river_border.sety((border_height + river_width) / 2)
lower_river_border.sety(-(border_height + river_width) / 2)

turtle.addshape("crocodile.gif")

for _ in range(number_of_enemies):

    enemy = turtle.Turtle()

    turtle.addshape("crocodile.gif")
    enemy.shape("crocodile.gif")
    enemy.up()
    x = -(window_width + enemy_width) / 2
    y = random.randint(-(river_width-enemy_height)/2, (river_width-enemy_height)/2)
    enemy.goto(x, y)

    enemies.append(enemy)

    enemy_speeds.append(random.randint(enemy_speed_min, enemy_speed_max))

turtle.shape("turtle")
turtle.left(180)
turtle.color("GreenYellow")
turtle.up()

turtle.ondrag(moveplayerturtle)

turtle.ontimer(updatescreen, update_interval)

turtle.done()

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

Любая помощь будет оценена по достоинству.


person John Hedlund-Fay    schedule 29.04.2017    source источник


Ответы (1)


Вы перепутали провода вплоть до обратного отсчета экрана-заставки — звоните не в то время в неподходящее время. Ниже мое предложение по минимальному исправлению. Во-первых, переопределите startgame() следующим образом:

def startgame():
    global countdown_number

    turtle.home()
    turtle.clear()
    turtle.left(270)

    if countdown_number > 0:
        for grey in range(0, 100, 5):
            turtle.forward(1)
            turtle.color("grey" + str(grey))
            turtle.write(countdown_number, align="center", font=("Arial", 200, "normal"))

        countdown_number -= 1

        turtle.ontimer(startgame, countdown_interval)

    else:
        for grey in range(0, 100, 5):
            turtle.forward(1)
            turtle.color("grey" + str(grey))
            turtle.write("GO!", align="center", font=("Arial", 200, "normal"))

        turtle.clear()

        turtle.ontimer(updatescreen, countdown_interval)

Затем некоторые небольшие изменения, чтобы приспособиться к этой перезаписи. В верхней части кода добавьте определение:

countdown_interval = 1000

рядом с определением update_interval.

В нижней части вашего кода вместо этого:

turtle.ontimer(updatescreen, update_interval)

turtle.done()

Сделай это:

turtle.ontimer(startgame, update_interval)

turtle.done()

Наконец, в updatescreen() удалите весь код, связанный с countdown_number:

global countdown_number
if countdown_number != "GO!":
    startgame()

if countdown_number == "GO!":

и при необходимости измените отступ тела этой функции.

Это должно сработать. Удачного уклонения!

person cdlane    schedule 29.04.2017