I am working through Cravens pygame tutorial and need some clarification. Here is the code that is causing the issue: CODE1:
import pygame
import random
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
GREEN = ( 0, 255, 0)
RED = ( 255, 0, 0)
pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("'Classy' Snow Globe")
class Snowstorm():
snow_list = []
snow_num = 0
snow_size = 0
snow_speed = 0
def get_snow(self):
for i in range(self.snow_num):
x = random.randrange(0, 700)
y = random.randrange(0, 500)
self.snow_list.append([x,y])
def draw_snow(self,screen):
for i in range(len(self.snow_list)):
pygame.draw.circle(screen,WHITE,self.snow_list[i],2)
self.snow_list[i][1] = self.snow_list[i][1] + self.snow_speed
if self.snow_list[i][1] > 500:
y = random.randrange(-50,-10)
self.snow_list[i][1] = y
x = random.randrange(0,700)
self.snow_list[i][0] = x
slow_storm = Snowstorm()
slow_storm.snow_num = 1
slow_storm.snow_size = 20
slow_storm.snow_speed = 1
slow_storm.get_snow()
med_storm = Snowstorm()
med_storm.snow_num = 2
med_storm.snow_size = 20
med_storm.snow_speed = 3
med_storm.get_snow()
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
slow_storm.draw_snow(screen)
med_storm.draw_snow(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
The get_snow method seems to be creating the same list for both instances of my Snowstorm class. Example: slow_storm calls get_snow method, the list is appended with [123,454] med_storm calls get_snow method, and gets the same list as slow_storm [123,454]
I changed the code by adding self.snow_list = [], and was able to produce the desired output. CODE2:
def get_snow(self):
self.snow_list = []
for i in range(self.snow_num):
x = random.randrange(0, 700)
y = random.randrange(0, 500)
self.snow_list.append([x,y])
I was also able to produce the correct output by using another variation of code. CODE3:
I added this before the def get_snow(self):
def __init__(self,list):
self.snow_list=list
Then modified the instances to:
slow_storm = Snowstorm([])
med_storm.get_snow([])
Question:
1. Why do the instances in the original code (CODE1) seem to be referencing the same list even though they are using self.snow_list?
2. What are the differences that enable CODE2 and CODE3 to work properly?
Thank you.
You put the snow_list = []
variable in the beginning of the class. This makes it a class variable which keeps it the same across all instances of the class. To make the lists separate, move snow_list = []
to be under def __init__():
part of the class.