private bool UpdateParticle(ref CCParticle p, float dt) { // life p.timeToLive -= dt; if (p.timeToLive > 0) { // Mode A: gravity, direction, tangential accel & radial accel if (m_nEmitterMode == CCEmitterMode.Gravity) { float radial_x = 0; float radial_y = 0; float tmp_x, tmp_y; float tangential_x, tangential_y; float x = p.pos.X; float y = p.pos.Y; if (x != 0 || y != 0) { float l = 1.0f / (float)Math.Sqrt(x * x + y * y); radial_x = x * l; radial_y = y * l; } tangential_x = radial_x; tangential_y = radial_y; //radial = CCPoint.ccpMult(radial, p.modeA.radialAccel); radial_x *= p.modeA.radialAccel; radial_y *= p.modeA.radialAccel; // tangential acceleration float newy = tangential_x; tangential_x = -tangential_y; tangential_y = newy; //tangential = CCPoint.ccpMult(tangential, p.modeA.tangentialAccel); tangential_x *= p.modeA.tangentialAccel; tangential_y *= p.modeA.tangentialAccel; // (gravity + radial + tangential) * dt //tmp = CCPoint.ccpAdd(CCPoint.ccpAdd(radial, tangential), modeA.gravity); //tmp = CCPoint.ccpMult(tmp, dt); //p.modeA.dir = CCPoint.ccpAdd(p.modeA.dir, tmp); //tmp = CCPoint.ccpMult(p.modeA.dir, dt); //p.pos = CCPoint.ccpAdd(p.pos, tmp); tmp_x = (radial_x + tangential_x + modeA.gravity.X) * dt; tmp_y = (radial_y + tangential_y + modeA.gravity.Y) * dt; p.modeA.dir.X += tmp_x; p.modeA.dir.Y += tmp_y; p.pos.X += p.modeA.dir.X * dt; p.pos.Y += p.modeA.dir.Y * dt; } // Mode B: radius movement else { // Update the angle and radius of the particle. p.modeB.angle += p.modeB.degreesPerSecond * dt; p.modeB.radius += p.modeB.deltaRadius * dt; p.pos.X = -CCMathHelper.Cos(p.modeB.angle) * p.modeB.radius; p.pos.Y = -CCMathHelper.Sin(p.modeB.angle) * p.modeB.radius; } // color p.color.R += (p.deltaColor.R * dt); p.color.G += (p.deltaColor.G * dt); p.color.B += (p.deltaColor.B * dt); p.color.A += (p.deltaColor.A * dt); // size p.size += (p.deltaSize * dt); if (p.size < 0) { p.size = 0; } // angle p.rotation += (p.deltaRotation * dt); return(true); } return(false); }
private void UpdateQuad(ref CCV3F_C4B_T2F_Quad quad, ref CCParticle particle) { CCPoint newPosition; if (m_ePositionType == CCPositionType.Free || m_ePositionType == CCPositionType.Relative) { newPosition.X = particle.pos.X - (s_currentPosition.X - particle.startPos.X); newPosition.Y = particle.pos.Y - (s_currentPosition.Y - particle.startPos.Y); } else { newPosition = particle.pos; } // translate newPos to correct position, since matrix transform isn't performed in batchnode // don't update the particle with the new position information, it will interfere with the radius and tangential calculations if (m_pBatchNode != null) { newPosition.X += m_obPosition.X; newPosition.Y += m_obPosition.Y; } CCColor4B color; if (m_bOpacityModifyRGB) { color.R = (byte)(particle.color.R * particle.color.A * 255); color.G = (byte)(particle.color.G * particle.color.A * 255); color.B = (byte)(particle.color.B * particle.color.A * 255); color.A = (byte)(particle.color.A * 255); } else { color.R = (byte)(particle.color.R * 255); color.G = (byte)(particle.color.G * 255); color.B = (byte)(particle.color.B * 255); color.A = (byte)(particle.color.A * 255); } quad.BottomLeft.Colors = color; quad.BottomRight.Colors = color; quad.TopLeft.Colors = color; quad.TopRight.Colors = color; // vertices float size_2 = particle.size / 2; if (particle.rotation != 0.0) { float x1 = -size_2; float y1 = -size_2; float x2 = size_2; float y2 = size_2; float x = newPosition.X; float y = newPosition.Y; float r = -CCMathHelper.ToRadians(particle.rotation); float cr = CCMathHelper.Cos(r); float sr = CCMathHelper.Sin(r); float ax = x1 * cr - y1 * sr + x; float ay = x1 * sr + y1 * cr + y; float bx = x2 * cr - y1 * sr + x; float by = x2 * sr + y1 * cr + y; float cx = x2 * cr - y2 * sr + x; float cy = x2 * sr + y2 * cr + y; float dx = x1 * cr - y2 * sr + x; float dy = x1 * sr + y2 * cr + y; // bottom-left quad.BottomLeft.Vertices.X = ax; quad.BottomLeft.Vertices.Y = ay; // bottom-right vertex: quad.BottomRight.Vertices.X = bx; quad.BottomRight.Vertices.Y = by; // top-left vertex: quad.TopLeft.Vertices.X = dx; quad.TopLeft.Vertices.Y = dy; // top-right vertex: quad.TopRight.Vertices.X = cx; quad.TopRight.Vertices.Y = cy; } else { // bottom-left vertex: quad.BottomLeft.Vertices.X = newPosition.X - size_2; quad.BottomLeft.Vertices.Y = newPosition.Y - size_2; // bottom-right vertex: quad.BottomRight.Vertices.X = newPosition.X + size_2; quad.BottomRight.Vertices.Y = newPosition.Y - size_2; // top-left vertex: quad.TopLeft.Vertices.X = newPosition.X - size_2; quad.TopLeft.Vertices.Y = newPosition.Y + size_2; // top-right vertex: quad.TopRight.Vertices.X = newPosition.X + size_2; quad.TopRight.Vertices.Y = newPosition.Y + size_2; } }
private void InitParticle(ref CCParticle particle) { // timeToLive // no negative life. prevent division by 0 particle.timeToLive = Math.Max(0, m_fLife + m_fLifeVar * CCRandom.Float_Minus1_1()); // position particle.pos.X = m_tSourcePosition.X + m_tPosVar.X * CCRandom.Float_Minus1_1(); particle.pos.Y = m_tSourcePosition.Y + m_tPosVar.Y * CCRandom.Float_Minus1_1(); // Color CCColor4F start; start.R = MathHelper.Clamp(m_tStartColor.R + m_tStartColorVar.R * CCRandom.Float_Minus1_1(), 0, 1); start.G = MathHelper.Clamp(m_tStartColor.G + m_tStartColorVar.G * CCRandom.Float_Minus1_1(), 0, 1); start.B = MathHelper.Clamp(m_tStartColor.B + m_tStartColorVar.B * CCRandom.Float_Minus1_1(), 0, 1); start.A = MathHelper.Clamp(m_tStartColor.A + m_tStartColorVar.A * CCRandom.Float_Minus1_1(), 0, 1); CCColor4F end; end.R = MathHelper.Clamp(m_tEndColor.R + m_tEndColorVar.R * CCRandom.Float_Minus1_1(), 0, 1); end.G = MathHelper.Clamp(m_tEndColor.G + m_tEndColorVar.G * CCRandom.Float_Minus1_1(), 0, 1); end.B = MathHelper.Clamp(m_tEndColor.B + m_tEndColorVar.B * CCRandom.Float_Minus1_1(), 0, 1); end.A = MathHelper.Clamp(m_tEndColor.A + m_tEndColorVar.A * CCRandom.Float_Minus1_1(), 0, 1); particle.color = start; particle.deltaColor.R = (end.R - start.R) / particle.timeToLive; particle.deltaColor.G = (end.G - start.G) / particle.timeToLive; particle.deltaColor.B = (end.B - start.B) / particle.timeToLive; particle.deltaColor.A = (end.A - start.A) / particle.timeToLive; // size float startS = m_fStartSize + m_fStartSizeVar * CCRandom.Float_Minus1_1(); startS = Math.Max(0, startS); // No negative value particle.size = startS; if (m_fEndSize == kCCParticleStartSizeEqualToEndSize) { particle.deltaSize = 0; } else { float endS = m_fEndSize + m_fEndSizeVar * CCRandom.Float_Minus1_1(); endS = Math.Max(0, endS); // No negative values particle.deltaSize = (endS - startS) / particle.timeToLive; } // rotation float startA = m_fStartSpin + m_fStartSpinVar * CCRandom.Float_Minus1_1(); float endA = m_fEndSpin + m_fEndSpinVar * CCRandom.Float_Minus1_1(); particle.rotation = startA; particle.deltaRotation = (endA - startA) / particle.timeToLive; // position if (m_ePositionType == CCPositionType.Free) { particle.startPos = ConvertToWorldSpace(CCPoint.Zero); } else if (m_ePositionType == CCPositionType.Relative) { particle.startPos = m_obPosition; } // direction float a = MathHelper.ToRadians(m_fAngle + m_fAngleVar * CCRandom.Float_Minus1_1()); // Mode Gravity: A if (m_nEmitterMode == CCEmitterMode.Gravity) { var v = new CCPoint(CCMathHelper.Cos(a), CCMathHelper.Sin(a)); float s = modeA.speed + modeA.speedVar * CCRandom.Float_Minus1_1(); // direction particle.modeA.dir = v * s; // radial accel particle.modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * CCRandom.Float_Minus1_1(); // tangential accel particle.modeA.tangentialAccel = modeA.tangentialAccel + modeA.tangentialAccelVar * CCRandom.Float_Minus1_1(); // rotation is dir if (modeA.rotationIsDir) { particle.rotation = -MathHelper.ToDegrees(CCPoint.ToAngle(particle.modeA.dir)); } } // Mode Radius: B else { // Set the default diameter of the particle from the source position float startRadius = modeB.startRadius + modeB.startRadiusVar * CCRandom.Float_Minus1_1(); float endRadius = modeB.endRadius + modeB.endRadiusVar * CCRandom.Float_Minus1_1(); particle.modeB.radius = startRadius; if (modeB.endRadius == kCCParticleStartRadiusEqualToEndRadius) { particle.modeB.deltaRadius = 0; } else { particle.modeB.deltaRadius = (endRadius - startRadius) / particle.timeToLive; } particle.modeB.angle = a; particle.modeB.degreesPerSecond = MathHelper.ToRadians(modeB.rotatePerSecond + modeB.rotatePerSecondVar * CCRandom.Float_Minus1_1()); } }