Basic Python Particle Class setup?

I’m curious how a working particle class could be used in BGE?
I have done some previous work with python classes managing other information.
What is the basic layout/template?
How does the lifetime of each particle work (along with say an aging alpha channel).

Thanks

Class?
There is no “particle” class. There are not even particles in the BGE. What we have are game objects.

To act as particles you can:

  • create them (at least as copy of an original object)
  • animate them (including material)
  • end them (can even happen automatically)

You can have a look at the How to: create fire and smoke with BGE particles. It is from 2.49, therefore the details of the GUI do not match, but the concept is still the same.

If you want some more ready-to-use you can search for easy-emit at the resource sub-forum.

what about making a mesh, that has little groups of 2 triangles worth of verticies,

and a uv atlas for particles, each particle is just 2 triangles?

1 giant mesh, 1 draw call for all particles?

like solarlunes voxelish demo thing?

Thanks for the replies!

What I meant was using a python class for a basic particle system, I think I should be able to do it though.
perhaps something like this?

class ExampleParticle

def __init__(self, lifetime, distance_to=0):
self.lifetime = lifetime
self.distance_to = distance_to

def main(self, lifetime, distance_to):
distance_to = getdistance()
if self.lifetime > 0:
self.lifetime -= 1:
else:
endParticle()

def endParticle(self):
self.endObject()?

def getdistance(self):
dist = own.getDistanceTo(spawner)
return dist


Then spawn in some instances of it?

New_particle = ExampleParticle(60)

Would something along these lines work? how would you end the object?

A little bit off topic but maybe glsl is a interesting thing for that too. I think with a good shader we could get more particle and make them more performant because they don’t need much CPU power.

I know there are some difficulties:
One problem is that you don’t can use bullet physics for the particles but I think many uses for particle don’t need collisions. Another thing that could makes trouble is that there are different ways to make a particle shader and it’s different which hardware can handle it.

But it’s only an idea and I don’t have much experience or knowledge about that topic , at the moment I spend some time to it but it’s far away from a finish particle system maybe in the future…

The BGE already can end objects added via addObject(template, emitter, lifetime).

If you want to detect the distance towards a given reference, you can calculate that on the fly.
If you want to perform operations dependent on the current age, you indeed need to store this information somewhere (e.g. in a property at the particle game object).

Alternatively you can use a different object as “particle model” and the game object as “particle representation” (view). I’m not sure if that is really worth.

As a guess, I presume, you should have a particle system class, and a particles subclass object.
What I want is that the particles are geometry shader generated. i dnt know if a shader can be controlled from outside! How ever, you could have the particles system spawn empties/invisible cubes with physics at the same positions as the particles.
If possible, you should also thread the particle system as it controls trajectory, speed or any other variable. It could help if a scene is supposed to have persistent particles (so that the particles don’t start spawning as the player arrives at the scene!), freezing the game!
But well, I’m still GLSL iliterate, so, yeah… My alternative would be as BPR said, use an object as the particle system and particles. and animate the vertices around. Then a single class could be enough.

Well, the object won’t do anything on its own. You need to keep it updated.

So, first create an instance of your class, you can pass all the needed variables to it at this time, like size, lifetime etc…
As a tip you can create the physical object first, then pass that to the class, if the class needs to get info about the scene, it can get them from the physical object

class Particle(object):
    def __init__(self,game_object,lifetime):
        self.game_object=game_object
        self.lifetime = lifetime
        self.scene = self.game_object.scene
        self.ending = False

On the particle manager you need:

def manage_particles(cont):
    own = cont.owner

    if "ini" not in own:
       own['particles'] = []
       particle_object = own.scene.addObject("particle",own,0)
       own['particles'].append(Particle(particle_object,60))
       own['ini'] = True
  • object is the class instance, it’s automatically passed

Next add that to some kind of particle manager. It can just be an update script attached to an object in the scene.

In the particle you need an update function:

class Particle(object):
    ...

    def update(self):
        self.lifetime -= 1
        if self.lifetime <= 0:
            self.ending = True
        else:
            self.do_stuff()

and you need the manager to update it:

def manage_particles(cont):
    own = cont.owner
    ...
    if own['particles']:
        next_generation = []
        for particle in own['particles']:
            if not particle.ending:
                next_generation.append(particle)
                particle.update()
            else:
                particle.game_object.endObject()

You’ll need to run this code every frame or as often as you intend to update the particles. When particles run out of steam they won’t be carried forward to the next generation, and so they will be lost. (I’m pretty sure the instance gets destroyed, but maybe someone with better knowledge can tell me about that. Does it need to be destroyed manually, or will it just go away once there are no active references to it?)

Alternatively, as monster suggests you can use the BGE’s built in structure to manage particles in the normal way.

p.s. if you are going to start down the dark path it might be better to organize your particle manager as a class/object too. Then your main game_loop can update the particle manager object each tic, and the manager will update all its particles in turn. The game_loop can also be a class, and so on.

Isn’t easyEmit addon good? However, I’d like someone to rewrite it for 2.75

Thanks smoking_mirror, this is what I was looking for.

@Thatimster, Probably off topic a little but I find that if you wanted to add and end a lot of objects from python with addObject, you will benefit more when you leave the lifetime at 0 and instead end all spawned objects via logic brick(attached with delay sensors for timing), this is probably due to the fact that python is bad at keeping a huge list of object’s “lifetime” in memory every frame

import bge
cont = bge.logic.getCurrentController()
spawner=cont.owner
if 'particleKeeper' not in spawner:
    spawner['particleKeeper']=bge.logic.getCurrentScene().objects['particleKeeper']

added = bge.logic.getCurrentScene().addObject('name',spawner,0)

added['Life']=60

spawner['particleKeeper']['PList'].append(added)


then have the object [‘particleKeeper’] sort through the list every frame subtracting 1 from Life,

if particle[‘Life’]<=0, end object, and pop from list?

Yeah, thats the basic idea, but when you use classes you can make it easier by farming the code out to the class.
Each particle has an update function so you just call that. But each object’s update function can be different. So adding new types of particle becomes very simple, you don’t have to change your main function at all because it doesn’t care what the object is doing. Just write a new custom update function for that particle. Particles can be subclassed too so they share chunks of code with their parent class. For example you have Fire, BlueFire, RedFire, GreenFire etc…

So turns out there is a life function on each object:

# import bge
import bge

# get controller 
cont = bge.logic.getCurrentController()

# get object that controller is attached to 
obj = cont.owner

# get the object's time left
amount = obj.life

I guess this could simplify both the “hack” method and the actual class method.