The program is supposed to update the value of the global variable int_choice
every time a player scores (it's a pong game)
int_choice
can only have a value of 1 or 0. If it's 1, the function left_or_right
"tells" the ball to go right, if it's 0, the ball goes left.
int_choice
is updated in few places: at the beginning it's initialized, then in the left_or_right()
function, then in the draw()
function.
Every time the user scores, the ball should be respawned from the centre of the table towards that user, but the ball always respawns twice in the same direction and then twice in the opposite direction and so on, regardless of who was the last one to score.
Here's the code:
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
You pass in the old value of direc
, before left_or_right
is called.
Say, you set int_cohice
to 1:
int_choice = 1
spawn_ball(direc) # old value of `direc`, nothing changed this yet
then in spawn_ball()
:
def spawn_ball(direction):
left_or_right()
so direction
is set the old value, but left_or_right()
sets it to a new value, which is then entirely ignored in spawn_ball()
. You use direction
throughout the function.
The quick fix is to use the return value of left_or_right()
; or use the direc
global. Since either operates on globals, there is no point in passing in direc
here:
int_choice = 1
spawn_ball() # don't pass anything in
and
def spawn_ball():
direction = left_or_right()
However, the better way is to always pass in a direction, and completely remove the (double) globals.
Just pass in a number, you can give that number symbolic names:
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)]
Note that the function returns new ball positions and velocity; store the result when you call the function:
ball_pos, ball_vel = spawn_ball(direction)
Perhaps the draw
function still treats these as globals, but that's no longer a concern for the spawn_ball()
function at the very least.
Now all you need to do is set one local variable to either LEFT
or RIGHT
to spawn a ball and pass that variable into the function.