This idea isn't really new. I already mentioned this topic a while ago but i decided to wait with the implementation until the new animation system is working so that it can be used for animated particles. To avoid any discussions about implementation details after the code is written i decided to document the whole system beforehand.
This article isn't finished. That is why it is in my personal directory. When i finished the article i will move it to Particle engine and link it from the front page in the RFC section.
implemented
not implemented
What is a particle engine?
A particle engine is a system that allows to create beautiful dynamic special effects based on creating and managing a large number of small, independent, moving sprites. Flames, smoke, fountains and waterfalls are just some examples what can be done with such an engine. For more information about particle engines see the Wikipedia article about particle systems.
Why a particle engine?
A particle engine would allow us to create a large variety of beautiful special effects with minimal effort that would outclass those of most other sprite based rpgs. The areas where particle effects could be used include but are not limited to:
- Environmental effects like waterfalls, fountains or smoke comming out of chimneys
- Visualisation of mystical phenomenons like teleporters or other points of interest
- Graphic effects for spells
- Visualisation of status effects
Implementation
The basic element of the particle engine is a special particle named "particleEngine". It maintains a tree of particle effects. Each particle has a position in three dimensional space (in this case the two dimensional game world is threatet as a flat plane in a three dimensional space). Based on the type of particle it might or might not have:
- Movement based on physical properties
- A visual representation (a single image or an animation)
- A list of emitters that create additional particles.
The Particles are derived class from the "Sprite" class so that they can be added to the maps sprite list to be drawn together with the other sprites by the "map" class.
Creation of effects
Effects are created by calling particleEngine->addEffect(). The arguments are a particle effect definition file, the map coordinates (pixel-based) and the map on which the effect should be created. This creates a host particle that can have any number of emitters. The host particle is returned so it can be manipulated further. It is possible to create multiple host particles in one particle effect file. In that case only the last particle is returned.
Effects that follow beings
Beings can gain control of a particle. This happens by calling the controlParticle() member function of the Being class.
The usual method to create a particle that follows a being is by calling particleEngine->addEffect() and pass the returned particle to controlParticle().
Note that when a Being takes control of a particle it disables the automatic deletion of the particle. The being is now responsible for requesting the deletion of the particle by calling Particle::kill(). When it does the particle will be deleted after its next update.
Homing particles
A particle will be attracted by another particle when its acceleration is greater than 0. When a particle is created by an emitter the attracting particle is the host particle of the effect but it can be changed by calling Particle::setDestination(). I would always recommend to use a parent particle of the particle as a target because a segvault will occur when the target particle is deleted.
The effect definition file
The effect definition files are xml documents describing one or more single particles or particle emitters. They can theoretically be loaded for all 6 ways to create effects.
<effect>
Is the root element of the XML document.
<particle>
Every effect is based on at least one particle. Often but not always these root particles function only as emitters that spawn new particles and have no appearance of their own. They have the following three required properties:
- position-x
- (initial) position on map relative to the position where the effect is created (pixel-based)
- position-y
- (initial) position on map relative to the position where the effect is created (pixel-based)
- position-z
- (initial) position on map relative to the position where the effect is created (pixel-based)
The following properties are optional:
- lifetime
- Lifetime in game-ticks. (default: unlimited)
- image
- path to the image that should be drawn at the position of the particle (default: no image)
In addition they can have any number of emitters
<emitter>
Emitters are always child-elements of a particle or another emitter. They create new particles themself which can also include emitters and so on. They also include a number of <property> child elements that define the initial properties of the created particles. When one of the following propertiy elements is missing the default value is used. The property elements have two or three properties. Either name and value or name, min and max.
They can also have any number of <emitter> childtags. When these exist all child-particles will be equipped with these emitters.
- position-x
- (initial) position on map relative to the parent particle (pixel-based) (default: 0)
- position-y
- (initial) position on map relative to the parent particle (pixel-based) (default: 0)
- position-z
- (initial) position on map relative to the parent particle (pixel-based) (default: 0)
- image
- path to the image that should be drawn at the position of the particles (default: no image)
- horizontal-angle
- clockwise angle of initial vector on horizontal plane in degree. 0° means straight right. (default: 0°)
- vertical-angle
- angle of initial vector in degree (default: 0°)
- power
- Initial speed of the particles in pixels/ game-tick (default: 0)
- gravity
- Downward acceleration of particles in pixels/game-tick² (default: 0)
- randomnes
- Random changes in the X, Y and Z vector. The unit is maximum pixels/game-tick/1000.
- lifetime
- lifetime in game ticks (default: -1 = unlimited)
- fade-in
- Number of game ticks until the lifetime has ended when the particle starts to disappear by fading into alpha. (default: 0 = disabled)
- fade-out
- Number of game ticks while the particles fade in to their full opacity.
- output
- Numbers of particles created per tick (default: 1)
- acceleration
- acceleration of particles towards the target in pixels/game-tick² (default: 0)
- momentum
- Momentum of the particles. Before adding the acceleration the old vectors are multiplied by this. A momentum of 1 creates a perfect newtonian object. A slightly lower momentum gives the impression that the particles are breaked. A higher momentum makes the particles accelerate forward what looks rather weird but could be useful for some effects. A negative momentum looks really ugly. (default: 1)
- die-distance
- Distance in pixels to the target that causes the destruction of the particles when reached. (Default: 0 = not destroyed on contact)