2016-07-29 229 views
0

程序问题应该更新每一次全局变量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 
+0

'random.randint(0,1)'是'random.randrange(2)'的别名。考虑使用后者。 –

+1

为什么你甚至使用*两个*全局意味着同样的事情?而你的'left_or_right()'函数可以用一个列表来代替:'directions = ['LEFT','RIGHT']'和directions [int_choice]'会在每次需要文本时将整数转换为文本。 –

+0

你也传递给'spawn_ball()'的方向,然后*调用'left_or_right()'。为什么要通过这个方向,然后调用一个函数来重新设置它?该函数也会返回方向,但您无处处忽略返回值。 –

回答

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()其设置为值,然后完全忽略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功能还是将它们视为全局,但是这不再是spawn_ball()功能的关心至少是:当你调用函数存储结果。

现在你需要做的是建立一个本地变量要么LEFTRIGHT产卵球和变量传递到函数。

1

你的问题,因为你在你的代码错误的时间更新变量。我们来看一个游戏结束后会发生什么的例子。

int_choice = 0 
spawn_ball(direc) 

您设置int_choice为0,然后调用spawn_ball(直销),但直销是方向 - 这还没有发生变化,只是int_choice了。所以现在direc已经绑定到你的spawn_ball函数中的“方向”变量。即使spawn_ball立即调用left_or_right(),那么只会更新direc,而不会指向,这意味着spawn_ball将继续与它最初传入的方向相同,而不管对left_or_right的调用如何。

快速的解决办法是说

def spawn_ball(direction): 
    direction = left_or_right() 

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