Python pygame — прыгающий шар (UnboundLocalError: локальная переменная ‘move_y’, на которую ссылаются перед назначением)

#python #pygame

#python #pygame

Вопрос:

Я хотел создать функцию, которая отвечает за отскок мяча от края экрана. Я знаю, что могу сделать это лучше с помощью функции math и Vector2, но мне интересно, почему у меня эта ошибка, и почему я могу запустить window без этой строки кода:

 if ball.y >= HEIGHT - 10:
    move_y = -vall_vel
 

Код

 class Ball:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color

    def draw(self, window):
        pygame.draw.circle(window, self.color, (self.x, self.y), 10)

ball = Ball(WIDTH // 2, HEIGHT // 2, red)

def main():
    run = True

    ball_vel = 10
    move_x = ball_vel
    move_y = ball_vel

    def update():
        WINDOW.fill(black)

        ball.draw(WINDOW)

        player.draw(WINDOW)
        pygame.display.update()

    def ball_move():
        
        if HEIGHT - 10 > ball.y > 0 and WIDTH - 10 > ball.x > 0:
            ball.x  = move_x
            ball.y  = move_y
        
        if ball.y >= HEIGHT - 10:
            move_y = -ball_vel

    while run:
        clock.tick(FPS)

        ball_move()

        update()
 

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

1. Вы должны объявить move_y как глобальную переменную, иначе ball_move() функция считает, что это локальная переменная.

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

3. @JohnGordon переменные move_x и move_y переопределяются в первых нескольких строках функции; они доступны для любых внутренних функций внутри main .

4. Я плохо скопировал и вставил свой код, но первые две строки кода просто ссылаются на 2 строки в функции ball_move() . Использование глобальной переменной мне очень помогло, так что спасибо.

5. @OakenDuck они доступны для чтения в глобальной области видимости, но не для присвоения .

Ответ №1:

Проблема вызвана функцией

Код, вызывающий проблему, находится в функции:

 def ball_move():

   if HEIGHT - 10 > ball.y > 0 and WIDTH - 10 > ball.x > 0:
       ball.x  = move_x
       ball.y  = move_y

   if ball.y >= HEIGHT - 10:
       move_y = -ball_vel
 

В функцию ball_move записывается переменная move_y . Это означает, что переменная объявлена внутри тела функции и является локальной переменной (local in ball_move ). Чтение переменной до ее объявления вызывает ошибку

UnboundLocalError: локальная переменная ‘move_y’, на которую ссылаются перед назначением

Вы должны использовать global оператор, если хотите интерпретировать переменную как глобальную переменную. На самом деле в функции существует переменная с тем же именем main . Но поскольку должна быть установлена та же переменная main , она также должна быть объявлена там как глобальная:

 def main():
    global run, move_x, move_y        # <---- ADD

    run = True
    ball_vel = 10
    move_x = ball_vel
    move_y = ball_vel

    def update():
        WINDOW.fill(black)
        ball.draw(WINDOW)
        player.draw(WINDOW)
        pygame.display.update()

    def ball_move():
        global move_x, move_y         # <---- ADD

        if HEIGHT - 10 > ball.y > 0 and WIDTH - 10 > ball.x > 0:
            ball.x  = move_x
            ball.y  = move_y
        if ball.y >= HEIGHT - 10:
            move_y = -ball_vel

    while run:
        clock.tick(FPS)
        ball_move()
        update()