#import "ParticleEffectSelfMade.h"
@implementation ParticleEffectSelfMade
-(id) init
{
return [self initWithTotalParticles:250];
}
-(id) initWithTotalParticles:(int)numParticles
{
if ((self = [super initWithTotalParticles:numParticles]))
{
// DURATION
// most effects use infinite duration
self.duration = kCCParticleDurationInfinity;
// for timed effects use a number in seconds how long particles should be emitted
//self.duration = 2.0f;
// If the particle system runs for a fixed time, this will remove the particle system node from
// its parent once all particles have died. Has no effect for infinite particle systems.
self.autoRemoveOnFinish = YES;
// MODE
// particles are affected by gravity
self.emitterMode = kCCParticleModeGravity;
// particles move in a circle instead
//self.emitterMode = kCCParticleModeRadius;
// some properties must only be used with a specific emitterMode!
if (self.emitterMode == kCCParticleModeGravity)
{
// centerOfGravity is misleading as it determines the offset where particles appear. The actual
// center of gravity is the node's position.
self.centerOfGravity = CGPointMake(-15, 0);
// gravity determines the particle's speed in the x and y directions
self.gravity = CGPointMake(-50, -90);
// radial acceleration affects how fast particles move depending on their distance to the emitter
// positive radialAccel means particles speed up as they move away, negative means they slow down
self.radialAccel = -90;
self.radialAccelVar = 20;
// tangential acceleration lets particles rotate around the emitter position,
// and they speed up as they rotate around (slingshot effect)
self.tangentialAccel = 120;
self.tangentialAccelVar = 10;
// speed is of course how fast particles move in general
self.speed = 15;
self.speedVar = 4;
}
else if (self.emitterMode == kCCParticleModeRadius)
{
// the distance from the emitter position that particles will be spawned and sent out
// in a radial (circular) fashion
self.startRadius = 100;
self.startRadiusVar = 0;
// the end radius the particles move towards, if less than startRadius particles will move
// inwards, if greater than startRadius particles will move outward
// you can use the keyword kCCParticleStartRadiusEqualToEndRadius to create a perfectly circular rotation
self.endRadius = 10;
self.endRadiusVar = 0;
// how fast the particles rotate around
self.rotatePerSecond = 180;
self.rotatePerSecondVar = 0;
}
// EMITTER POSITION
// emitter position is at the center of the node (default)
// this is where new particles will appear
self.position = CGPointZero;
self.posVar = CGPointZero;
// The positionType determines if existing particles should be repositioned when the node is moving
// (kCCPositionTypeGrouped) or if the particles should remain where they are (kCCPositionTypeFree).
self.positionType = kCCPositionTypeFree;
// PARTICLE SIZE
// size of individual particles in pixels
self.startSize = 40.0f;
self.startSizeVar = 0.0f;
self.endSize = kCCParticleStartSizeEqualToEndSize;
self.endSizeVar = 0;
// ANGLE (DIRECTION)
// the direction in which particles are emitted, 0 means upwards
self.angle = 0;
self.angleVar = 0;
// PARTICLE LIFETIME
// how long each individual particle will "life" (eg. stay on screen)
self.life = 5.0f;
self.lifeVar = 0.0f;
// PARTICLE EMISSION RATE
// how many particles per second are created (emitted)
// particle creation stops if self.particleCount >= self.totalParticles
// you can use this to create short burst effects with pauses between each burst
self.emissionRate = 30;
// normally set with initWithTotalParticles but you can change that number
self.totalParticles = 250;
// PARTICLE COLOR
// A valid startColor must be set! Otherwise the particles may be invisible. The other colors are optional.
// These colors determine the color of the particle at the start and the end of its lifetime.
startColor.r = 1.0f;
startColor.g = 0.25f;
startColor.b = 0.12f;
startColor.a = 1.0f;
startColorVar.r = 0.0f;
startColorVar.g = 0.0f;
startColorVar.b = 0.0f;
startColorVar.a = 0.0f;
endColor.r = 0.0f;
endColor.g = 0.0f;
endColor.b = 0.0f;
endColor.a = 1.0f;
endColorVar.r = 0.0f;
endColorVar.g = 0.0f;
endColorVar.b = 1.0f;
endColorVar.a = 0.0f;
// BLEND FUNC
// blend func influences how transparent colors are calculated
// the first parameter is for the source, the second for the target
// available blend func parameters are:
// GL_ZERO GL_ONE GL_SRC_COLOR GL_ONE_MINUS_SRC_COLOR GL_SRC_ALPHA
// GL_ONE_MINUS_SRC_ALPHA GL_DST_ALPHA GL_ONE_MINUS_DST_ALPHA
self.blendFunc = (ccBlendFunc){GL_SRC_ALPHA, GL_DST_ALPHA};
// shortcut to set the blend func to: GL_SRC_ALPHA, GL_ONE
//self.blendAdditive = YES;
// PARTICLE TEXTURE
self.texture = [[CCTextureCache sharedTextureCache] addImage: @"fire.png"];
}
return self;
}
@end
1.
For example, if you have a particle effect that creates stars around yourplayer-character’s head, you would want the stars to follow the player as he movesaround. You can achieve this effect by setting this property:
self.positionType = kCCPositionTypeGrouped;
On the other hand, if you want to set your player on fire and you want the particles tocreate a trail-like effect as the player moves around, you should set the positionTypeproperty like this:
self.positionType = kCCPositionTypeFree;
The free movement is best used with effects like steam, fire, engine exhaust smoke, andsimilar effects that move around with the object they are attached to and should give theimpression of not being connected to the object that emits these particles.
TIP: By tweaking particle lifetime, the total number of particles allowed in the system, and theemissionRate, you can create burst effects by allowing the stream of particles to be frequentlyinterrupted just because the number of particles on-screen is limited and new particles areemitted relatively quickly. On the other hand, if you notice undesirable gaps in your particlestream, you need to either increase the number of allowed particles or preferably reduce thelifetime and/or emission rate. In that case, you should use emissionRate =totalParticles / life.
(source color * source blend function) + (destination color * destination blendfunction)
GL_ZERO
GL_ONE
GL_SRC_COLOR
GL_ONE_MINUS_SRC_COLOR
GL_SRC_ALPHA
GL_ONE_MINUS_SRC_ALPHA
GL_DST_ALPHA
GL_ONE_MINUS_DST_ALPHA
You’ll find more information on the OpenGL blend modes and details about the blendcalculations in the OpenGL ES documentation at
www.khronos.org/opengles/documentation/opengles1_0/html/glBlendFunc.html.
TIP: Since it’s hard to imagine which blend functions will create which results with varyingimages, I’d like to point you to an article that describes the most common blend operations withexample images:
www.machwerx.com/2009/02/11/glblendfunc/.
Even more interesting is the Visual glBlendFunc tool developed by Anders Riggelsen:
www.andersriggelsen.dk/OpenGL/.
With any HTML5-compatible browser you can play withvarious images and blend functions to see the results instantly.
Note that you can also modify the blendFunc property of other cocos2d nodes, namely, allnodes that conform to the CCBlendProtocol such as the classes CCSprite,CCSpriteBatchNode, CCLabelTTF, CCLayerColor, and CCLayerGradient.