全局变量设置问题

时间:2016-07-29 14:46:54

标签: python global-variables pong

该程序应该在每次玩家得分时更新全局变量int_choice的值(这是一个乒乓球游戏)

int_choice的值只能为1或0.如果为1,则函数left_or_right“告诉”球向右移动,如果为0,则球向左移动。

int_choice在几个地方更新:在开头初始化,然后在left_or_right()函数中,然后在draw()函数中。

每次用户得分时,球应该从桌子的中心向该用户重新生成,但是球总是在相同的方向上重生两次,然后在相反的方向上重复两次,依此类推,无论是谁最后一个得分。

以下是代码:

import random

int_choice = random.randint(0,1)
direc = None

def left_or_right():
    global direc, int_choice
    if int_choice == 0:
        direc = "LEFT"
    elif int_choice == 1:
        direc = "RIGHT"
    return direc

def spawn_ball(direction):
    left_or_right()
    global ball_pos, ball_vel # these are vectors stored as lists
    ball_pos = [WIDTH / 2, HEIGHT / 2]
    if direction == "LEFT":
        ball_vel[0] = (random.randrange(12, 25)*(-0.1))
        print "Velocity[0]: ", ball_vel[0]
        ball_vel[1] =  (random.randrange(6, 19)*(-0.1))
    elif direction == "RIGHT":
        ball_vel[0] = (random.randrange(12, 25)*(0.1))
        print "Velocity[0]: ", ball_vel[0]
        ball_vel[1] =  (random.randrange(6, 19)*(-0.1))
        print "Velocity[1]: ", ball_vel[1]

def new_game():
    global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel, direc
    global score1, score2, 
    spawn_ball(direc)
    score1 = 0
    score2 = 0

def draw(canvas):
    global remaining_names, score1, score2, paddle1_pos, paddle2_pos,          ball_pos, ball_vel, BALL_RADIUS, direc
    global int_choice


    # update ball
    ball_pos[0] += ball_vel[0]
    ball_pos[1] += ball_vel[1]
    if ball_pos[1] - BALL_RADIUS <= 0:
        ball_vel[1] = ball_vel[1] + (ball_vel[1] * (-2))     
    elif ball_pos[1] + BALL_RADIUS >= HEIGHT:
        ball_vel[1] = ball_vel[1] + (ball_vel[1] * (-2))
    elif ball_pos[0] - BALL_RADIUS <= (0 + PAD_WIDTH):
        if (ball_pos[1] > paddle1_pos) and (ball_pos[1] < (paddle1_pos + PAD_HEIGHT)):
            ball_vel[0] = ball_vel[0] + (ball_vel[0] * (-2.1))
        else:
            int_choice = 1
            spawn_ball(direc)
            score2 = score2 + 1

    elif (ball_pos[0] + BALL_RADIUS) >= (WIDTH - PAD_WIDTH):
        if (ball_pos[1] > paddle2_pos) and (ball_pos[1] < (paddle2_pos + PAD_HEIGHT)):
            ball_vel[0] = ball_vel[0] + (ball_vel[0] * (-2.1))
        else:
            int_choice = 0
            spawn_ball(direc)
            score1 = score1 + 1

2 个答案:

答案 0 :(得分:4)

在调用direc之前,您传递left_or_right值。

说,您将int_cohice设置为1:

int_choice = 1
spawn_ball(direc)  # old value of `direc`, nothing changed this yet

然后在spawn_ball()

def spawn_ball(direction):
    left_or_right()

因此direction设置值,但left_or_right()将其设置为 new 值,然后完全忽略<{1}}中的。您在整个功能中使用spawn_ball()

快速解决方法是使用direction的返回值;或使用left_or_right()全局。既然要么对全局变量进行操作,那么传递direc就没有意义了:

direc

int_choice = 1
spawn_ball()  # don't pass anything in

然而,更好的方法是始终向一个方向传递,并完全删除(双)全局变量。

只需传入一个数字,就可以给出这个数字的符号名称:

def spawn_ball():
    direction = left_or_right()

注意功能返回新球位置和速度;调用函数时存储结果:

LEFT, RIGHT = 0, 1  # symbolic names for direction

def spawn_ball(direction):
    ball_pos = [WIDTH / 2, HEIGHT / 2]
    if direction == LEFT:  # using the global symbolic name
        return ball_pos, [
            random.randrange(12, 25)*(-0.1),
            random.randrange(6, 19)*(-0.1)]
    else:   # naturally the other option is going to be RIGHT
        return ball_pos, [
            random.randrange(12, 25)*(0.1)
            random.randrange(6, 19)*(-0.1)]

也许ball_pos, ball_vel = spawn_ball(direction) 函数仍然将它们视为全局变量,但这至少不再是draw函数的关注点。

现在您需要做的就是将一个 local 变量设置为spawn_ball()LEFT以生成一个球并将该变量传递给该函数。

答案 1 :(得分:1)

您的问题存在是因为您在代码中的错误时间更新了变量。让我们看一下游戏结束后会发生什么的例子。

int_choice = 0
spawn_ball(direc)

你将int_choice设置为0,然后你调用spawn_ball(direc),但是direc是方向 - 它还没有改变,只有int_choice有。所以现在direc已经绑定到spawn_ball函数中的“direction”变量。即使spawn_ball立即调用left_or_right(),只会更新direc,而不是方向,这意味着无论对left_or_right的调用是什么,spawn_ball都将继续使用与最初传入的方向相同的方向。 / p>

快速解决方案就是说

def spawn_ball(direction):
    direction = left_or_right()

这可能会解决这个问题。但是,我建议你重构一下你的代码 - 这是非常糟糕的风格。像往常一样传递全局变量很容易出现这样的错误 - 使用通过函数调用传递的本地变量是一个更好的选择。