0
\$\begingroup\$

so I've been trying to create a basic particle system in pygame which I can later expand upon but I've run into a spot of bother creating the particle emitter. Obviously what's supposed to happen is it's supposed to create a new particle every frame (or a set of particles) but instead it just alters the particle that's created first time round. I understand why this is happening, as far as the game is concerned, every frame I add the same object to the particle list so when I call the update function it calculates the positional and velocity sums multiple times, what I'm having trouble with is fixing it. How would I go about making a new particle every time?

My existing classes for this are as follows:

class Particle():
    def __init__(self, pos, vel, accel, image):
        self.pos = pos
        self.vel = vel
        self.accel = accel
        self.life = 255
        self.lifecount = 1
        self.image = image

    def update(self):
        self.vel.add(self.accel)
        self.pos.add(self.vel)
        self.life -= self.lifecount

    def is_dead(self):
        if self.life <= 0:
            return True
        else:
            return False

class Emitter():
    def __init__(self, pos):
        self.pos = PVector(pos[0], pos[1])
        self.particles = []
        self.part_list = [Particle(self.pos, PVector(0,2), PVector(0,0), pygame.image.load("resources/particles/fireball.png"))]

    def update(self):
        self.particles.extend(self.part_list)
        for p in self.particles[:]:
            p.update()
            if p.is_dead():
                self.particles.remove(p)

    def draw(self, surface):
        for p in self.particles:
            x = p.pos.x
            y = p.pos.y
            temp = pygame.Surface((p.image.get_width(), p.image.get_height())).convert()
            temp.blit(surface, (-x, -y))
            temp.blit(p.image, (0, 0))
            temp.set_alpha(p.life)        
            surface.blit(temp, (x, y))

The positions, velocities and accelerations are all part of a vector class with vector math functions.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Just create the particles in the update method:

# Load the fireball once
fireball = pygame.image.load("resources/particles/fireball.png")

class Emitter():
    def __init__(self, pos):
        self.pos = PVector(pos[0], pos[1])
        self.particles = []
        self.part_list = [] # Create an empty list of particles

    def update(self):
        # Add a new particle
        p_pos = PVector(self.pos.x, self.pos.y)
        p = Particle(p_pos, PVector(0,2), PVector(0,0), fireball)
        self.particles.append(p)

        # Update existing particles
        for p in self.particles[:]:
            p.update()
            if p.is_dead():
                self.particles.remove(p)
    ...
\$\endgroup\$
3
  • \$\begingroup\$ Just tried this, same issue as above. Sorry. \$\endgroup\$ Jul 8, 2013 at 18:18
  • \$\begingroup\$ Ok, you are using the same pos vector over and over (Emitter.pos). I added a line creating a new vector based on the previous one, but perhaps you have a clone method in PVector which would look nicer. \$\endgroup\$
    – pmoleri
    Jul 8, 2013 at 18:45
  • \$\begingroup\$ Thank you! It finally works! You sir are a God amongst men! :D \$\endgroup\$ Jul 8, 2013 at 18:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .