2016-07-29 38 views
0

zunächst das Programm soll den Wert der globalen Variablen int_choice jedes Mal, wenn ein Spieler Partitur aktualisieren (es ist ein Pong-Spiel)Ausgabe mit einer globalen Variablen

int_choice kann nur einen Wert von 1 oder 0. Wenn es 1, die Funktion left_or_right "erzählt" der Ball nach rechts gehen, wenn es 0 ist, geht der Ball nach links.

int_choice ist an einigen Stellen aktualisiert: am Anfang ist es initialisiert, dann in der left_or_right() Funktion, dann in der draw() Funktion.

Jedes Mal, wenn der Benutzer ein Tor erzielt, sollte der Ball von der Mitte des Tisches zu diesem Benutzer neu gespawnt werden, aber der Ball erscheint immer zweimal in die gleiche Richtung und dann zweimal in die entgegengesetzte Richtung und so weiter, egal wer war der Letzte, der zählt.

Hier ist der 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 
+0

'random.randint (0,1)' ist ein Alias ​​für 'random.randrange (2)'. Erwäge, das Spätere zu verwenden. –

+1

Warum verwenden Sie überhaupt * zwei * globals, die dasselbe bedeuten? Und Ihre 'left_or_right()' Funktion könnte einfach durch eine Liste ersetzt werden: 'directions = ['LINKS', 'RECHTS']', und 'directions [int_choice]' würden die ganze Zahl jedes Mal in Text umwandeln, wenn Sie den Text benötigen. –

+0

Sie übergeben auch die Richtung in 'spawn_ball()', die dann * auch 'left_or_right()' * * aufruft. Warum in die Richtung gehen, dann eine Funktion aufrufen, um sie erneut einzustellen? Die Funktion gibt auch die Richtung zurück, aber Sie ignorieren den Rückgabewert überall. –

Antwort

4

Sie gehen in den alten Wert von direc, bevor left_or_right aufgerufen wird.

Say, setzen Sie int_cohice-1:

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

dann in spawn_ball():

def spawn_ball(direction): 
    left_or_right() 

so direction die alten Wert eingestellt ist, aber left_or_right() setzt es auf einen neuen Wert , die dann völlig ignoriert wird in spawn_ball(). Sie verwenden direction während der gesamten Funktion.

Die schnelle Lösung besteht darin, den Rückgabewert left_or_right() zu verwenden; oder verwenden Sie die direc global.Da entweder auf Globals arbeitet, gibt nebenbei in direc hier kein Punkt ist:

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

und

def spawn_ball(): 
    direction = left_or_right() 

Allerdings ist der bessere Weg zu immer Pass in eine Richtung, und die vollständig entfernen (Doppel) Globals.

Geben Sie einfach in einer Reihe, können Sie diese Zahl symbolischen Namen geben:

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)] 

Beachten Sie, dass die Funktion kehrt neue Kugelpositionen und Geschwindigkeit; das Ergebnis speichern, wenn Sie die Funktion aufrufen:

ball_pos, ball_vel = spawn_ball(direction) 

Vielleicht ist die draw Funktion noch behandelt diese als Globals, aber das ist nicht mehr eine Sorge um die spawn_ball() Funktion zumindest.

Alles was Sie jetzt tun müssen, ist eine Set lokale Variable entweder LEFT oder RIGHT einen Ball laichen und diese Variable in die Funktion übergeben.

1

Ihr Problem besteht, weil Sie die Variable zur falschen Zeit in Ihrem Code aktualisieren. Schauen wir uns ein Beispiel an, was nach dem Ende eines Spiels passiert.

int_choice = 0 
spawn_ball(direc) 

Sie setzen int_choice auf 0, dann rufen Sie spawn_ball (DIREC), aber DIREC ist die alt Richtung - es ist noch nicht geändert hat, nur int_choice hat. Also wurde direc jetzt an die "direction" Variable in deiner spawn_ball Funktion gebunden. Auch wenn spawn_ball sofort left_or_right() aufruft, wird nur direc aktualisiert, nicht Richtung, was bedeutet, dass spawn_ball mit der gleichen Richtung weiterläuft, in der es ursprünglich übergeben wurde, egal was der Aufruf von left_or_right getan hat.

würde die schnelle Lösung

def spawn_ball(direction): 
    direction = left_or_right() 

Welche wahrscheinlich beheben, dieses Problem zu sagen sein. Allerdings würde ich vorschlagen, dass Sie Ihren Code ein wenig umgestalten - es ist ein sehr schlechter Stil. Das Umgehen globaler Variablen wie Sie sind so anfällig für Fehler wie diese - die Verwendung von Locals, die durch Funktionsaufrufe weitergegeben werden, ist eine viel bessere Option.