Skip to main content
gamedev.net
🔒 Locked

Particles

Started by MrPickle Mar 19, 2009 at 2:30 PM 7 replies 1.1k views
Original Post
MrPickle
MrPickle
I am developing a 2D 'game' and I would like to implement a particle engine. I have a rough idea how to do it but I have a few questions. 1) "Curving" the particle's path? I am still in High/Secondary school therefore I have only done basic 2D vector math so bear with me here. I have the beginning velocity, final velocity of the particle and the 'life' of the particle; let a be the starting velocity and b be the finishing velocity. I have worked out that to work out the current velocity of the particle I think I have to do: a + (c/life)b where c is the amount of time the particle has existed and life is the maximum life of the particle, but I think that this will just cause the particle to go in a straight line from a to b? 2) Gravity I think this may be the solution to my problem above, how do I apply gravity to the particles? just add the gravity vector onto the particle? I'd like to make the gravity act from a point, and dissipate the further away you are from the source. Would I have to use the equation above but instead of life and time use strength and length, so something like this: c + (√(c.x × d.x + c.y × d.y)/strength)d I have tried to make my post as comprehendable as possible.
Here to learn :)
fastcall22
fastcall22
Quote:
Original post by MrPickle
I think that this will just cause the particle to go in a straight line from a to b?


Nope, you stated that a and b are both velocities; what you have here is a constant deceleration. If you were to graph the position, it would look something similar to an f(x) = x2 graph.

Quote:
Original post by MrPickle
how do I apply gravity to the particles? just add the gravity vector onto the particle? I'd like to make the gravity act from a point, and dissipate the further away you are from the source.


For particle position, p1
Point of gravity, p2
Gravity constant, g
Area of effect, E
Effect strength, Ef = max( 0, E - (p1 - p2).length() )
The direction gravity, vf = (p1 - p2).normalize()

The resulting force is (Ef / E × g) × vf

EDIT:
Was that needlessly complicated? :/
MrPickle
MrPickle
Thank you, _fastcall.

I am still struggling to see why it would be a curve, maybe I should try plotting it out on graph paper.

Could you please explain to me why my gravity equation wouldn't work?
I will try plotting this one out too, and yours.

[Edit]
I have plotted the first one out on a graph, and it was a straight line?

[Edited by - MrPickle on March 19, 2009 4:02:17 PM]
Here to learn :)
fastcall22
fastcall22
Quote:
Original post by MrPickle
I am still struggling to see why it would be a curve,

...

[Edit]
I have plotted the first one out on a graph, and it was a straight line?


The distance traveled over time is a curve, as in, the particle will slow down as it reaches point B. What you see however, it travels in a straight line. However, it depends on weather or not your velocities also specify a direction.

Quote:
Original post by MrPickle
Could you please explain to me why my gravity equation wouldn't work?


Don't get me wrong, I haven't said it wouldn't work. :) But I wasn't sure what c and d were in the equation.

EDIT:
Nevermind, I'm guessing d is the direction, and c is the position. You're also working with a distance / strength, if the distance is close to zero, then there isn't much of an effect at all, and the further you are from the gravity, the stronger the effect. You might want to consider describing the formula in terms of how far you want the gravity to effect, and how strong you want the gravity in that area.
MrPickle
MrPickle
Oh yes, sorry for not mentioning what c and d were.

c was the position of the particle and d was the gravity's force.
Yeah, looking back it will get stronger the further away from the source you are. That's the opposite of what I want.

I'm starting to get it now, thanks.
Here to learn :)
CDProp
CDProp
If you got a straight line when you graphed it out, it's probably because you graphed velocity vs. time, which is a straight line. All that means is that there's no acceleration. If you plot position vs. time, which is much closer to what you'd actually visualize in your game, then it should be a curve.


fastcall22
fastcall22
Quote:
Original post by CDProp
If you plot position vs. time, which is much closer to what you'd actually visualize in your game, then it should be a curve.


Erm, even a position vs. time graph would look like a line (that is, assuming velocities a and b are scalar values and are supplemented with a direction vector during simulation):




MrPickle's gravity calculations should change that straight line anyway. :3
frob
frob
Rather than hard-coding your particle system, you might want to consider a data-driven approach.

An easy solution is to have a list of operators and values.

When you spawn the particles you assign a position, velocity, and any other attributes as desired.


Operators could include Add/Subtract, Multiply/Divide, and various Clamp operations. (Note: subtract is adding a negative value. Divide is simply multiply by 1/x.)

the code is basically:
for each list entry {  switch (entry.operator)  {    case Add:           particle.velocity += entry.value; break;    case Multiply:        particle.velocity *= entry.value; break;    case ClampX:        particle.velocity.X.Clamp( entry.low, entry.high ); break;    case ClampY:        particle.velocity.Y.Clamp( entry.low, entry.high ); break;    ...  }}


It is easy to add age-based effects, transformations (changes to scale, rotation, and orientation), animations or coloring, and countless other operations as you need them.


Gravity is introduced by adding negative height velocity every frame, then optionally clamping at the terminal velocity. The same is true for other simple curves.

Higher order curves are done with multiplication or other operations you choose to define.

An example would be something like this:

<emitter>  <spawn>    <position x=0 y=0 z=0 />    <velocity>      <x type=random min=-2 max=2 />      <y type=constant value=12 />      <z type=random min=-2 max=2 />    </velocity>    <scale value=1.8 />    <rate type=variable min=0.1 max=0.8 />  </spawn>  <update>   <!-- gravity and vertical air resistance-->   <operator type=add>     <y type=constant value=-0.02>     <y type=clamp min=-1.7 max=10>   </operator>   <!-- slowly shrink and flicker -->   <operator type=transform>     <scale type=random min=-0.02 max=0.015>     <scale type=clamp min=0.1 max=2>   </operator>  </update></emitter>


It is fairly easy to put together a tool to play with the variables and see the results instantly.
MrPickle
MrPickle
Thank you all, I think I will begin to code it now and see how things go.
Here to learn :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.