Загрузка данных


from turtle import Screen, Turtle
from random import randint

# --- Настройки экрана (создаются один раз) ---
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("white")
screen.tracer(0)  # Отключаем автообновление для плавности

# --- Игровые параметры ---
FINISH_LINE_Y = 210
FINISH_LINE_Y_2 = -215
FINISH_LINE_X = 250
FINISH_LINE_X_2 = -250
CAR_SPEED = 10
CAR_SPAWN_CHANCE = 5  # 1 из 5 (20%)

# --- Глобальные переменные игры ---
game_is_on = True
player = None
cars = []
message_turtle = None  # Для отображения текста "Победа" или "Поражение"


# --- Класс для машин ---
class Car(Turtle):
    def __init__(self, y_position):
        super().__init__()
        self.penup()
        self.shape("square")
        self.shapesize(stretch_wid=1, stretch_len=2)
        self.color(self.random_color())
        self.goto(300, y_position)
        self.setheading(180)  # Едет влево

    def random_color(self):
        colors = ["red", "blue", "green", "orange", "purple", "cyan"]
        return colors[randint(0, len(colors) - 1)]

    def move(self):
        self.forward(CAR_SPEED)

    def is_off_screen(self):
        return self.xcor() < -320

    def respawn(self):
        self.goto(300, randint(FINISH_LINE_Y_2, FINISH_LINE_Y))
        self.color(self.random_color())


# --- Основная логика игры ---
def game_loop():
    global CAR_SPEED, game_is_on

    # Если игра окончена (победа/поражение), выходим из функции
    if not game_is_on:
        return

    for car in cars[:]:  # Используем срез для безопасного удаления/итерации
        car.move()

        # Проверка столкновения с игроком
        if car.distance(player) < 20:
            game_over()
            return  # Останавливаем текущий цикл

        # Если машина уехала за экран, возвращаем её назад
        if car.is_off_screen():
            car.respawn()

    # Шанс появления новой машины
    if randint(1, CAR_SPAWN_CHANCE) == 1:
        new_car = Car(randint(FINISH_LINE_Y_2, FINISH_LINE_Y))
        cars.append(new_car)

    # Увеличиваем сложность (скорость машин)
    if player.ycor() > 150 and CAR_SPEED < 20:
        CAR_SPEED += 1

    # Проверка победы (достижение финиша)
    if player.ycor() >= FINISH_LINE_Y:
        victory()
        return  # Останавливаем текущий цикл

    screen.update()  # Обновляем экран вручную
    screen.ontimer(game_loop, 100)  # Вызываем эту функцию снова через 100 мс


# --- Функции завершения игры ---
def game_over():
    global game_is_on, message_turtle
    game_is_on = False
    player.hideturtle()

    # Скрываем все машины
    for car in cars:
        car.hideturtle()

    # Отображаем сообщение о поражении
    message_turtle = Turtle()
    message_turtle.penup()
    message_turtle.hideturtle()
    message_turtle.color("red")
    message_turtle.write("ИГРА ОКОНЧЕНА\nНажми ENTER для рестарта", align="center", font=("Arial", 24, "normal"))


def victory():
    global game_is_on, message_turtle
    game_is_on = False
    player.hideturtle()

    for car in cars:
        car.hideturtle()

    # Отображаем сообщение о победе
    message_turtle = Turtle()
    message_turtle.penup()
    message_turtle.hideturtle()
    message_turtle.color("green")
    message_turtle.write("ПОБЕДА!\nНажми ENTER для рестарта", align="center", font=("Arial", 24, "normal"))


# --- Функция рестарта ---
def restart_game():
    global game_is_on, player, cars, message_turtle

    # Убираем сообщение о победе/поражении, если оно есть
    if message_turtle:
        message_turtle.clear()

    game_is_on = True

    # Сбрасываем позицию игрока и показываем его
    player.goto(0, FINISH_LINE_Y_2)
    player.showturtle()

    # Сбрасываем все машины: скрываем старые и очищаем список
    for car in cars:
        car.hideturtle()
    cars.clear()

    # Сбрасываем сложность к начальному уровню
    global CAR_SPEED
    CAR_SPEED = 10

    # Запускаем игровой цикл заново
    game_loop()


# --- Функции управления игроком ---
def move_up():
    if player.ycor() < FINISH_LINE_Y:
        player.forward(10)


def move_down():
    if player.ycor() > FINISH_LINE_Y_2:
        player.backward(10)


def move_left():
    if player.xcor() > FINISH_LINE_X_2:
        x = player.xcor() - 10
        player.goto(x, player.ycor())


def move_right():
    if player.xcor() < FINISH_LINE_X:
        x = player.xcor() + 10
        player.goto(x, player.ycor())


# --- Настройка управления ---
def setup_controls():
    screen.listen()
    screen.onkeypress(move_up, "Up")
    screen.onkeypress(move_down, "Down")
    screen.onkeypress(move_left, "Left")
    screen.onkeypress(move_right, "Right")

    # Привязываем рестарт к клавише Enter (важно: только когда фокус на окне)
    screen.onkeypress(restart_game, "Return")


# --- Инициализация и запуск ---
if __name__ == "__main__":
    # Создаем игрока (черепашку)
    player = Turtle()
    player.shape("turtle")
    player.color("black")
    player.penup()
    player.goto(0, FINISH_LINE_Y_2)
    player.setheading(90)

    setup_controls()

    game_loop()  # Старт первого цикла игры

    screen.mainloop()