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\$ Commented 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\$ Commented Jul 8, 2013 at 18:45
  • \$\begingroup\$ Thank you! It finally works! You sir are a God amongst men! :D \$\endgroup\$ Commented Jul 8, 2013 at 18:50

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.