I want to create a class Ball
, and make a list of objects generated by user for that class. I will then reference this list in run()
to draw user generated objects in pygame
. My problems are as follows:
When I try to reference Ball(a, v, r...)
it says Ball
is referenced before my definition. Any help is appreciated!
HERE IS FULL ERROR:
File "/Users/.../Desktop/.../python/promot.py", line 66, in run
balls.append(Ball(a, v, r, c, x_pos, y_pos)) #here i get error
^^^^
UnboundLocalError: cannot access local variable 'Ball' where it is not associated with a value
import pygame
import math
pygame.init()
#screen
framespd = 30 #what is frame speed for gravity = 9.81
gravity = 1
t = 0.01
clock = pygame.time.Clock()
width, height = 1000, 1000
pygame.display.set_caption("Orbit Take 1")
screen = pygame.display.set_mode([width, height])
class Ball:
def __init__(self, angle, velocity, radius, color, x_pos, y_pos):
self.angle = angle
self.velocity = velocity
self.radius = radius
self.color = color
self.x_pos = x_pos
self.y_pos = y_pos
def draw(self):
self.circle = pygame.draw.circle(screen, self.color, (self.x_pos, self.y_pos), self.radius)
def true_velocity_x(self):
true_velocity_x = self.velocity * math.cos(self.angle)
def true_velocity_y(self):
true_velocity_y = self.velocity * math.sin(self.angle)
new_velocity_y = true_velocity_y + (gravity * t)
#def update position(self):
#x pos = x velocity
#y pos += y velocity
balls = []
def run():
value = True
while value:
clock.tick(framespd)
# Balls in sim
number_balls = int(input("How many balls: "))
while len(balls) < number_balls:
# Variables for Ball
a = input("Angle: ")
v = input("Velocity: ")
r = input("Radius: ")
c = input("Color: ")
x_pos = '0'
y_pos = '500'
balls.append(Ball(a, v, r, c, x_pos, y_pos)) #here i get error "local variable "Ball" defined in enclosing scope on line 24 referenced before assignment"
screen.fill('black')
#draw ball
for Ball in balls:
Ball.draw(pygame.display.set_mode((width, height)))
#update position
for event in pygame.event.get():
if event.type == pygame.QUIT:
value = False
pygame.display.flip()
pygame.quit()
run()
My first attempt is referenced in bold as "something else I tried", but I am having trouble using classes outside of their initialization with out errors. My next attempt was "current attempt" which does not show anything when I run.
For the first ball this was working correctly but then it encountered the
for Ball in balls:
statement and then you had a Ball in your namespace so the global variable is overwritten, instead we can call the object ball and run .draw on the ball object.
There was a way around this (if you insist on calling the local variable Ball) by passing the class into the function that I demonstrated as well.
def run(cls = Ball):
import pygame
import math
pygame.init()
# screen
framespd = 30 # what is frame speed for gravity = 9.81
gravity = 1
t = 0.01
clock = pygame.time.Clock()
width, height = 1000, 1000
pygame.display.set_caption("Orbit Take 1")
screen = pygame.display.set_mode([width, height])
class Ball:
def __init__(self, angle, velocity, radius, color, x_pos, y_pos):
self.angle = angle
self.velocity = velocity
self.radius = radius
self.color = color
self.x_pos = x_pos
self.y_pos = y_pos
self.balls = []
def draw(self, width, height):
# We need the inputs of width and height to pass to set_mode
pygame.display.set_mode((width, height))
#self.circle = pygame.draw.circle(screen, (0, 0, 255), (250, 250), (self.x_pos, self.y_pos), self.radius)
# below will always draw a blue circle - tweak color, center and radius to be variables so that you can
# generate multiple balls with different properties
self.circle = pygame.draw.circle(screen, color=(0, 0, 255), center=(250, 250), radius=75)
def true_velocity_x(self):
true_velocity_x = self.velocity * math.cos(self.angle)
def true_velocity_y(self):
true_velocity_y = self.velocity * math.sin(self.angle)
new_velocity_y = true_velocity_y + (gravity * t)
# def update position(self):
# x pos = x velocity
# y pos += y velocity
balls = []
def run():
value = True
while value:
clock.tick(framespd)
# Balls in sim
number_balls = int(input("How many balls: "))
while len(balls) < number_balls:
# Variables for Ball
a = input("Angle: ")
v = input("Velocity: ")
r = input("Radius: ")
c = input("Color: ")
x_pos = '0'
y_pos = '500'
balls.append(Ball(a, v, r, c, x_pos,
y_pos)) # here i get error "local variable "Ball" defined in enclosing scope on line 24 referenced before assignment"
screen.fill('black')
# draw ball
# call our ball 'ball' so it doesn't overwrite out global class
for ball in balls:
ball.draw(width, height)
# update position
for event in pygame.event.get():
if event.type == pygame.QUIT:
value = False
pygame.display.flip()
pygame.quit()
run()