My particle engine

Started by
10 comments, last by gnomer 18 years, 7 months ago
Hi guys I got my basic particle engine working. It lets you click to make little burts of pixels. Download. I was trying to make it look like sparks are flying but at the moment it just looks like a few pixels :( Anyone know what I should do next to make decent effects? Thanks
Advertisement
Nice!

Make some fire. Make it so that the inner particles(from the mouse) is yellow,the ones outside that redder, etc. Basicly so that the farther away from the mouse the particles is, the more red it becomes(or yellow, or any color you want)
Hope I was helpful. And thank you if you were!
cool idea, il try that

edit: Hmm I added red_change, green_change, blue_change to the particle structure and then in the update_particle code added stuff so that the colours where changed eg "red = particle->color.r + (particle->red_change * time_passed * DELTA);".

Problem is this changes the colours over time so all the particles change together , not sure how to make them change colour depending on how far away from the exploation they are.

Also another thing I'm trying to figure out is how come the "exploation" of pixels looks fake. If you set it to make say 1000 particles you notice that each particle keeps a set distance away from each other and it expands in a square shape, instead of looking like a dynamic exploation.
Heres what I meen:


Thanks

[Edited by - kzar on August 23, 2005 1:59:55 PM]
Hey, looks good man!

This may or may not help, but to get rid of that evil square in my engine, I made it form a circle using sin and cos.

//basically, for each degree around a circle and a given increment, this pushes back a new particle at a P(X,Y) and at a Dx(lu_Cos[j]) Dy(lu_Sin[j]) etc etc.for(int j=0; j<360; j+=inc){                m_ParticlePool.push_back(new ParticleSprite(X, Y, lu_Cos[j], lu_Sin[j], Life, iAlpha, W, H, File, Type));            }// this is my sin cos init codefor(int i=0; i<360; i++){   lu_Cos = FLOAT_TO_FIXP(  cos((i*3.14)/180)  );   lu_Sin = FLOAT_TO_FIXP(  sin((i*3.14)/180)  );}// this is my fixpoint code#define FP_SHIFT 16#define FP_SCALE 16typedef int FIXPOINT;#define INT_TO_FIXP(n) (FIXPOINT((n << FP_SHIFT)))#define FLOAT_TO_FIXP(n) (FIXPOINT((float)n*FP_SCALE))


Even with this circle, you still dont have a dynamic explosion, the key is to randomize the velocities after fixed-point calculations. In essence, just throw in a random fraction generator with your velocity (Dx, Dy) calculations and it should work just fine.

Hope this helps, and If I need to clarify stuff, Please Let me know!

toXic1337
toXic1337
I have something similar in my Asteroids game (just posted it - check it out! ). It's far from perfect, but it might give you some ideas about taking into account direction of force and stuff like that. You can download it here...

My Website
hi ,

I made a really basic particle system demo a month ago. I ran into the same problem of getting a very artificial look because the particles expanded in a square fashion.

Then like toxic1337 suggested, I used the circle equation and randomized the velocities as well.

The explosion was much better but it still appeared artificial because all particles had the same range. So I gave each particle a random starting energy.( analogous to potential energy). The energy depletes as the particle moves. When the energy of a particle is zero, it dissapears. Now you'll get a really neat explosion with a lot of random particle behaviour.

Anyway hope that helped.

- v-EktOr-->
Thanks for the replies, I have been busy but I got a chance to read them and my explotion is alot better already. The zip has overwritten the old one and is at the original url.

Here is a picture of what it looks like if I click once:


and if i spam the scroll wheel:


What I am stuck with is how to make an explotions without using exactly 360 particles look good.

Also I was wondering how to vary the velocitys so that it isnt a perfect circle but still roughly is a circle.

I was also curious if I should do somthing special incase the x / y vol turns out to be 0 because I'm sure if you spam the explotions you can see a line along the different axis.

Incase you cant be bothered opening up the source (I probably wouldn't) here is the function I wrote with your help.
void circle_explosion(int x, int y){    int i;    float x_vol, y_vol;    float rand_x, rand_y;        for (i = 0; i < 360; i++)    {        x_vol = cos((i*3.14)/180) * 16;        y_vol = sin((i*3.14)/180) * 16;                rand_x = (rand() % 10) - 5;        rand_y = (rand() % 10) - 5;                x_vol += rand_x;        y_vol += rand_y;        add_particle(x, y, x_vol, y_vol, yellow, 50, 0, 0, -50);    }}


Thanks for the help
Quote:Original post by kzar
What I am stuck with is how to make an explotions without using exactly 360 particles look good.


So you are placing them evenly in a circle?
The way I usually make my explosions is I iterate through every particle, then set the particle's velocity to a random X and Y, and then reduce the velocity to a random number that represents its speed.

// Initialize the particles...srand(time(NULL)); // Requires the inclusion of stdlib.h and time.hfor(int i = 0; i < particlenumber; i++) {	particle.velocity.x = (float)(rand() % (RAND_MAX - 1)) / (float)RAND_MAX;	particle.velocity.y = (float)(rand() % (RAND_MAX - 1)) / (float)RAND_MAX;	float mag = sqrt(pow(particle.velocity.x, 2) +		pow(particle.velocity.y, 2)); // Requires the inclusion of math.h, calculates the magnitude of the velocity vector	particle.velocity.x = (particle.velocity.x / mag) *		(float)(rand() % (RAND_MAX - 1)) / (float)RAND_MAX;	particle.velocity.y = (particle.velocity.y / mag) *		(float)(rand() % (RAND_MAX - 1)) / (float)RAND_MAX;	// The code above reduces the velocity to have a magnitude between 0 and 1	// This is all greatly simplified if you write a vector class to do this stuff for you	// Sorry if this code has errors, but I hope you get the general idea}
Random random random random!

All of my particle systems have insanely large quantities of parameters so I can specify min/max random ranges to modify a single parameter. Add enough particles and keep it pretty random and you'll end up with a nice non-artificial dispersal pattern.

What I've always done to make an explosion particle effect is to generate a random direction for each particle (can work in two or three dimensions the same way). Then I randomly scale the base particle speed, lifetime, opacity change (actually, I usually base the opacity on the lifetime), etc. Then I let the particle system's update function pass down the elapsed time to each particle and let it run the simple physics to update the position (and other attributes). It's simple, quick, and I've never encountered any instances of excess accumulation to a quadrant -- it's always been pretty even dispersed along all 360 degrees.

void Particle::Spawn( vector vPos, vector vRandomUnitVector, float fSpeed ){	m_vForces(0.0f,0.0f,0.0f);	m_vAcceleration(0.0f,0.0f,0.0f);	m_vVelocity = vRandomUnitVector * fSpeed;	m_vPos = vPos;}void Particle::Update( float fDt ){	m_vAcceleration += m_vForces * fDt;	m_vVelocity += m_vAcceleration * fDt;	m_vPos += m_vVelocity * fDt;}


I wrote that off the top of my head but that's the typical particle I use. I almost never use the forces and acceleration components as constant velocity is most common. You could make acceleration be gravity and forces be wind or something like that. The random unit vector passed in would be the direction (create a vector with randomized values and normalize it) and scale it by the speed to get your velocity. Position is obvious -- it typically should start all in the same position and the physics will move it.
I wanted to check it out but it doesn't load. SDL_ttf.dll was not found. I guess I need something else installed to run SDL progs?

This topic is closed to new replies.

Advertisement