1. Home
  2. Computing & Technology
  3. Delphi Programming
Real-time 2D particle systems (with gravitation!)
Page 2: Sample projects.
 More of this Feature
• Page 1: Particle systems

• T1TestProject.zip
• T2TestProject.zip
• GDI T3TestProject.zip

Printer friendly versionPrinter friendly version
 Join the Discussion
"Post your questions, concerns, views and comments to this article..."
Discuss!
 Related Resources
• Game programming
• Graphics programming
• Mathematics in Delphi

   The T1TestProject
Since we are going to be using the GDI to display pixels that represent our particles, I have provided a function for you in this project called SetPixel(X, Y, Color : Integer); In order to use it in your own programs, you must have a TBitmap created as shown in the example project. This example generates 7000 simple particles that expand out from the center of the form. The code is very straightforward and easy to follow. I have added a little sparkle to it to make it more interesting for the eye. Go ahead and run the program and review the code. After you have finished, come back so we can discuss gravitation between particles!

Click to download T1TestProject.zip

TIP: Often in the examples, you will see Random(1000)/1000 passed as a parameter for something like Force, Mass, or Angle. The reason for this is simple. The higher the value you use to generate random numbers, the more refined your particles will look. For example, if you passed Random(10)/10, you only have a possibility of 10 different types of particle that range in values from 0 to 0.9. If you use Random(100)/100, you have a possibility of values from 0 to 0.99, etc. The higher the value, the more precise the effect becomes. It will not affect performance to use the higher values and I highly recommend using them because it makes things look better!

   The T2TestProject
This example looks almost identical to the last example. However, I have added a twist. I have turned on the gravitation capability for each particle. Particles that have their gravity turned on will now attract each other automatically when the MoveAllParticles procedure is called. Check out the way I initialize the particles. The parameters I am passing may look intimidating, but they are constructed in that way so that the effect looks cool. Go ahead and take a look at the code and play around with some of the parameters I have passed into the CreateCompleteParticle proc. This will give you a feel for how the library works!

Click to download T2TestProject.zip

TIP: Please note that I have used the Application.OnIdle event. This is important because if you were to use a TTimer instead of the OnIdle event, you are subject to the idiosyncrasies of how the timer works on different machines. Using timers, I have seen it run super fast on a 400mhz and then run super slow on an 800mhz when using the exact same code! Avoid timers when doing graphics…

T2TestProject Discussion
To create the gravity effect, I am using a basic gravitation formula that I took from a physics book. You can find it in the MoveAllParticles proc in ParticleUnit.Pas. All you have to do to turn on this effect is to set the ParticleHasGravity variable to True and then give the particle mass and a gravitation range. There is a pseudo-flaw in my design however. Theoretically, objects that are attracted to each other continue to speed up towards each other as they move closer together. This is how we slingshot satellites around planets to speed them on their way deep into our solar system.

When it comes to infinitely small particles like we have in my library (they have no true size outside of a XY coordinate), I had to find a way to make it so they stopped gravitating once particles reached certain proximity to each other. I have called this the Gravitation Range and I measure it in pixels. If a particles coordinate is outside of that range, it will gravitate, if it falls inside of that range, it will not gravitate. Of course, this isn’t realistic, but if you do not do this, the attracting particles will literally rip themselves apart. To witness this for yourself, change the gravitation value in the example from 45 to 5. The particles will gain so much speed from gravitating towards each other that they will fly off the screen super fast. In real life, you can imagine the gravitation range as the surface of a planet and the core of the planet acts as the infinitely small X,Y position. If a satellite fell into the gravitation range, it would hit the planet surface. Since I am obviously not going to destroy my particle, I simple turn off the particles gravitation until it is back outside of the gravitation range. To help you visualize Gravitation Range, refer to example 2.0. I only have the gravitation range of the center particle displayed, but the other two particles will have gravitation ranges as well!

Another important thing to note is that gravitation is slow. You will be hard pressed to get more than 300 gravitating particles going at once and still have it look good. The reason for this is simple. Every particle in your universe is affected by all of the other particles in your universe. This means if you have 100 gravitating particles, each particle must analyze the gravitational effect of the other 99 particles. For all 100 particles to be analyzed, it must calculate 100x100 = 10,000 calculations in order to move 100 particles! With 300 particles, it requires 90,000 calculations per move!

Theoretically, I should be adding up the total change each particle makes on the root particle and then average it out before I apply the change. I did not do this because I did not think of it until now. I think it will make the effects of gravity look even more realistic. If you’re brave, you may wish to add that functionality to my library!

As you play with this demo, you will notice that the "atoms" will tend to not only pick up speed, but the entire molecule will drift on its own! The reason it drifts is because some particles have more mass than other particles. If the program randomly generates more particles with a higher mass moving in the same general direction, those heavy particles will pull the other ones along, thus we have movement.

Particle system 2

   The T3TestProject
Clear as mud? Great! Let’s move on for we need to discuss gravity wells. This time, I will have two examples for you; One using the GDI and the other using DirectDraw. Since DirectDraw is part of DirectX, you must have DirectX version 4.0 or later installed on your O/S if you wish to view the second example.

Click to download the GDI T3TestProjectGDI.zip

General gravity well discussion
Gravity wells behave similar to particles with gravity. However, they are different in two ways. First, they do not move on their own. Second, they can attract or repel particles, but they themselves are not attracted or repelled by particles or other gravity wells. Gravity wells, like particles, have a Gravitation Range that prohibits gravity within a certain pixel range. If your gravitation range is too small, then incoming particles will speed up so fast that they will sling-shot themselves out of orbit into the far reaches of your 2D universe, never to return!

T3TestProjectGDI discussion
In the example the RED dot shows where the attracting gravity well is and an AQUA dot that points to where the repelling gravity well is.

T3TestProjectDD discussion
This code is about a year old already. I was learning DirectX and writing this particle unit at the same time so the code isn’t the greatest. The crappiest thing about DirectX is that the concepts are easy to learn, but its pain in the arse to actually implement. At any rate, this demo requires that your monitor can handle 800x600 resolution at 256 colors. It fires a bunch of particles into the air and I have placed a gravity well in the bottom left corner of the screen. This attracts the particles in such a way that it looks like a water fountain with wind. Enjoy!

TIP: There are a few optimizations that would really help speed up the particle library. One is to switch to integer-based math instead of floating point values. Floats make things chunk whereas integer based math makes things fast. Another is to find a way to move the particle gravitation formulae into a lookup table. I’m not sure how it could be done effectively, but I’m sure if some time was spent on it, a clever way would be found. Unfortunately, I’m too lazy to do it myself.

   Particle summary
Well, we have reached the end of this lesson. I hope you had as much fun viewing these examples as I have had writing them. I would like to now take the time to share something with you and then state a simple belief I have. Mathematics is not my strong point. Having little aptitude for math does not mean you do not have what it takes to program graphics or create fantastic looking effects! What it does take is a motivating desire to accomplish it. In these examples, I took a simple physics formulae that you can find in any book and then used some basic geometry to create a particle system that dazzles. It is not how much you know; it is what you do with what you do know! To stress my point, I will show you my final example of particle programming. I have not provided the source code for this because it is going to be implemented into a game a group of us is working on. This is an explosion generator using the exact technology I have just shown you. Although the particle code I had to write to make it work is more complex than what I have shown in these examples, you should be able to see the basic elements that I explained earlier.

First page > What is a particle system, particle, system, gravitation? > Page 1, 2

Explore Delphi Programming

More from About.com

  1. Home
  2. Computing & Technology
  3. Delphi Programming

©2008 About.com, a part of The New York Times Company.

All rights reserved.