0

So to preface this, I am a Education student whos minor is computer science. My main focus is not coding and I may have made some big mistakes in here that I have not seen yet. My current issue is that I will receive the error

"Traceback (most recent call last):
  File "/home/user/Downloads/PongV1.py", line 158, in <module>
    main()
  File "/home/user/Downloads/PongV1.py", line 13, in <module>
    game.play()
  File "/home/user/Downloads/PongV1.py", line 42, in <module>
    self.update()
  File "/home/user/Downloads/PongV1.py", line 77, in <module>
    self.ball.move()
  File "/home/user/Downloads/PongV1.py", line 136, in <module>
    game.score2 = game.score2 + 1
builtins.NameError: name 'game' is not defined  

Whenever I try to run this game. I know it is currently in downloads, but I'm running this off of a hastily put together VM machine.As far as I know, I called my score 1/score 2 Variable decently well.

The goal of what I am trying to do is get the scores in the corners to update when the ball hits the wall. Currently, that is located in the def move section

This is what my screen looks like when I try to run this program

Thank you all for looking!

  # pygame v2

import pygame
import uaio
import math
import time
from pygame.locals import *

# User-defined functions
def main():
    surface = create_window()
    game = Game(surface)
    game.play()
    pygame.quit()

# Create window 
def create_window():
    pygame.init()
    surface_size = (700,600)
    title = 'Pong'
    surface = pygame.display.set_mode(surface_size)
    pygame.display.set_caption(title)
    return surface
# define class games
class Game:
    def __init__ (self, surface):
        self.surface = surface   #locations and surface colors of games
        self.bg_color = pygame.Color('black')
        self.pause_time = 0.01
        self.close_clicked = False
        self.continue_game = True
        self.ball = Ball(pygame.Color('white'),[350,300],5,[6,2], surface)
        self.paddle= Paddle(pygame.Color('white'),(100,300),100,100, surface)
        self.score1 = 0
        self.score2 = 0

    def play(self):    #playing the game while the game is not closed
        self.draw()
        while not self.close_clicked:
            self.handle_event()
            if self.continue_game:
                self.update()
                self.decide_continue
            self.draw()
            time.sleep(self.pause_time)

def handle_event(self): #continuing the game
    event = pygame.event.poll()
    if event.type == QUIT:
        self.close_clicked = True

def draw(self):  #drawing the balls and paddles
    self.surface.fill(self.bg_color)
    self.ball.draw()
    self.paddle.draw()
    self.draw_score()
    pygame.display.update()

def draw_score(self):
    string = str(self.score1)
    location = 0,0
    size = 80
    #fg_color = pygame.Color('white')
    uaio.draw_string(string, self.surface,location,size)

    string = str(self.score2)
    location = 650,0
    size = 80
    #fg_color = pygame.Color('white')
    uaio.draw_string(string, self.surface,location,size)

def paddlecollide(self):
    self.paddle.collide_right(x, y)
    self.paddle.collidge_left(x, y)        

def update(self): #updating the movement of the ball
    self.ball.move()
    self.ball.collide(self.paddle)


def decide_continue(self): # deciding to continue teh game
    pass

class Paddle: #defining paddle

def __init__(self, color, left, width, height, surface):
   #location of paddle etc
    self.color = color
    self.left = left
    self.surface = surface
    self.width = width
    self.height = height
    self.paddle1 = pygame.Rect(140,270,20,80)
    self.paddle2 = pygame.Rect(540,270,20,80)
    #return self.paddle1, self.paddle2


def draw(self):
    #drawing paddle
    pygame.draw.rect(self.surface, self.color, self.paddle1)
    pygame.draw.rect(self.surface, self.color, self.paddle2)

def collide_left(self, x, y):
    return self.paddle1.collidepoint(x, y)

def collide_right(self, x, y):
    return self.paddle2.collidepoint(x, y)    

class Ball: #defining ball

def __init__(self, color, center, radius, velocity, surface):
    #charactersitics of said ball

    self.color = color
    self.center = center
    self.radius = radius
    self.velocity = velocity
    self.surface = surface


def draw(self):
    #drawing the ball
    pygame.draw.circle(self.surface, self.color, self.center, self.radius)

def move(self):

    # how the ball moves as well as ist velocity
    size = self.surface.get_size()
    for coord in range(0, 2):
        self.center[coord] = (self.center[coord] + self.velocity[coord]) 
        if self.center[coord] < self.radius:
            self.velocity[coord] = -self.velocity[coord]
            Game.score1 = Game.score1 + 1
        if self.center[coord] + self.radius > size[coord]:
            self.velocity[coord] = -self.velocity[coord]
            Game.score2 = Game.score2 + 1





def collide(self, paddles):
    xcoord =0 
    if paddles.collide_left(self.center[0], self.center[1]):
        self.velocity[xcoord] = -self.velocity[xcoord]

    if paddles.collide_right(self.center[0], self.center[1]):
        self.velocity[xcoord] = -self.velocity[xcoord]        

        #if x_velocity <= 0:
        #    collide = False
        #    
        #else: collide = True 

main()

  • Game.score2 = Game.score2 + 1 is sitting in ball, where it has no access to Game, which is not a variable anyway. – Jeremy Kahan Oct 28 '16 at 04:27
  • so see http://stackoverflow.com/questions/10791588/getting-container-parent-object-from-within-python for how to let ball finds its parent and so be able to increment score. – Jeremy Kahan Oct 28 '16 at 04:40

1 Answers1

1

The problematic line is this one (in your given code):

Game.score2 = Game.score2 + 1

There are two things wrong with this line:

  • Firstly, you are trying to use a variable that doesn't exist. Game is the name of a class that you have defined, you must create a new Game object and assign it to a variable before it can be used. I see that you have, which leads me onto problem 2...
  • Scope. You have defined the variable game in the function main. However, this variable will have been created locally. It cannot be accessed anywhere but the function it was defined in (with some exceptions). I recommend reading this stackoverflow answer to understand scope a little better.

score1 and score2 are both defined within the Games class. In the main function (line 12), a new Games object is created, and assigned to the variable games. This variable is local, and can only be accessed within the function main.

Now, you have 2 options. The first option would be to remove the variables score1 and score2 from the Games class altogether, and have them as separate variables defined in the main body of the program. This would allow them to be accessed anywhere (obviously you would have to change any references to game.score1 or game.score2.

The second, and in my opinion preferable option, would be to make the variable game a global variable. In your main function, the code would look like this:

def main():
    surface = create_window()
    global game
    game = Game(surface)
    game.play()
    pygame.quit()

Then, remember to de-capitalise any references to the Game class outside of your main function, so that your using the variable game, lie so:

Game.score1 = Game.score1 + 1

becomes

game.score1 = game.score1 + 1

I hope I explained this clearly enough. I would really recommend reading up on how scope and classes work in python before delving too far into pygame.

Community
  • 1
  • 1
Inazuma
  • 178
  • 3
  • 13