I am currently trying to write a program that creates 20 random dots on the screen and times how long it takes you to click them in succession (they shouldn't appear all at once). Clearly, my code isn't finished but I keep getting an error message saying that "Particle object isn't iterable." Could anyone help me out? Thanks! (I know my particle list is a bit ridiculous too, but what can you do? :-))
import pygame
import random
import math
import sys
background_colour = (255,255,255)
(width, height) = 600,500
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('DBS Test')
circle1 = (pygame.draw.circle(screen, (255, 255, 255), (300, 250), 25, 25))
def addVectors(angle1, length1, angle2, length2):
x = math.sin(angle1) * length1 + math.sin(angle2) * length2
y = math.cos(angle1) * length1 + math.cos(angle2) * length2
angle = 0.5 * math.pi - math.atan2(y, x)
length = math.hypot(x, y)
return (angle, length)
def findParticle(particles, x, y):
for p in particles:
if math.hypot(p.x-x, p.y-y) <= p.size:
return p
return None
class Particle:
def __init__(self, position, size):
self.x, self.y = position
self.size = size
self.colour = (255, 0, 0)
self.thickness = 20
def display(self):
pygame.draw.circle(screen, self.colour, (self.x, self.y), self.size, self.thickness)
particle_one = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_two = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_three = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_four = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_five = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_six = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_seven = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_eight = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_nine = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_ten = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_eleven = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_twelve = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_thirteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_fourteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_fifteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_sixteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_seventeen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_eighteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_nineteen = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_twenty = Particle((random.randint(0,600), random.randint(0,500)), 20)
particle_one.display()
selected_particle = None
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
(mouseX, mouseY) = pygame.mouse.get_pos()
selected_particle = findParticle(particle_one, mouseX, mouseY)
elif event.type == pygame.MOUSEBUTTONUP:
selected_particle = None
if selected_particle:
(mouseX, mouseY) = pygame.mouse.get_pos()
dx = mouseX - selected_particle.x
dy = mouseY - selected_particle.y
particle_two.display()
pygame.display.flip()
def main():
pass
if __name__ == '__main__':
main()
The problem is that you pass a single particle instance, but the findParticle
function expects an iterable (for example a list). You can create a list of particles when the program starts and then pass this list to the function.
import pygame
import random
import math
pygame.init() # Initialize all pygame modules.
background_colour = (255,255,255)
screen = pygame.display.set_mode((600, 500))
clock = pygame.time.Clock()
def findParticle(particles, x, y):
for p in particles:
if math.hypot(p.x-x, p.y-y) <= p.size:
return p
return None
class Particle:
def __init__(self, position, size):
self.x, self.y = position
self.size = size
self.colour = (255, 0, 0)
def display(self):
pygame.draw.circle(screen, self.colour, (self.x, self.y), self.size)
# Create a list for the particles.
particles = []
for _ in range(20):
particle = Particle((random.randint(0,600), random.randint(0,500)), 20)
particles.append(particle) # Append the new particle.
# Or use a list comprehension:
# particles = [Particle((random.randint(0,600), random.randint(0,500)), 20) for _ in range(20)]
selected_particle = None
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
(mouseX, mouseY) = pygame.mouse.get_pos()
# Now pass the particles list instead of a single particle.
selected_particle = findParticle(particles, mouseX, mouseY)
elif event.type == pygame.MOUSEBUTTONUP:
selected_particle = None
if selected_particle:
# Set the x and y-position of the particle at the same time.
selected_particle.x, selected_particle.y = pygame.mouse.get_pos()
# Clear the screen, then draw the particles.
screen.fill(background_colour)
for particle in particles:
particle.display()
pygame.display.flip()
clock.tick(30) # Limits the frame rate to 30 fps.
pygame.quit()