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
\$\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\$
  • \$\begingroup\$ Just tried this, same issue as above. Sorry. \$\endgroup\$ – Okinawa Terminal Jul 8 '13 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 '13 at 18:45
  • \$\begingroup\$ Thank you! It finally works! You sir are a God amongst men! :D \$\endgroup\$ – Okinawa Terminal Jul 8 '13 at 18:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.