public void draw(Canvas canvas) { for (int i = 0; i < mParticleCount; ++i) { Particle p = mParticles[i]; if (null != p) { Point newPos; if (mPositionType == PositionType.POSITION_GROUP) { newPos = Point.sub(mPosition, p.pos); } else { newPos = Point.sub(p.startPos, p.pos); } canvas.save(); canvas.translate(newPos.x, newPos.y); p.draw(canvas); canvas.restore(); } } }
public void update(float dt) { if (mIsActive && mEmissionRate > 0) { float rate = 1.0f / mEmissionRate; // issue #1201, prevent bursts of particles, due to too high emitCounter if (mParticleCount < mTotalParticles) { mEmitCounter += dt; } while (mParticleCount < mTotalParticles && mEmitCounter > rate) { this.addParticle(); mEmitCounter -= rate; } mElapsed += dt; if (mDuration != -1 && mDuration < mElapsed) { this.stopEmitting(); } } mParticleIdx = 0; if (mIsVisible) { boolean needInvalidate = mParticleIdx < mParticleCount; while (mParticleIdx < mParticleCount) { Particle p = mParticles[mParticleIdx]; // life p.timeToLive -= dt; if (p.timeToLive > 0) { // Mode A: gravity, direction, tangential accel & radial accel if (mEmitterMode == EmitterMode.MODE_GRAVITY) { Point tmp, radial, tangential; // radial acceleration if (p.pos.x != 0 || p.pos.y != 0) { radial = Point.Normalize(p.pos); } else { radial = new Point(); } tangential = radial; radial = Point.mult(radial, p.modeA.radialAccel); // tangential acceleration float newY = tangential.x; tangential.x = -tangential.y; tangential.y = newY; tangential.multBy(p.modeA.tangentialAccel); // (gravity + radial + tangential) * dt // tmp = Point.add(Point.add(radial, tangential), modeA.gravity); tmp = tangential; tmp.addBy(radial); tmp.addBy(modeA.gravity); tmp.multBy(dt); p.modeA.dir.addBy(tmp); p.pos.addBy(Point.mult(p.modeA.dir, dt)); } else { // Mode B: radius movement // 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 = (float) (-Math.cos(p.modeB.angle) * p.modeB.radius); p.pos.y = (float) (-Math.sin(p.modeB.angle) * p.modeB.radius); } // color int r = Color.red(p.color) + (int) (p.deltaColor.r * dt); int g = Color.green(p.color) + (int) (p.deltaColor.g * dt); int b = Color.blue(p.color) + (int) (p.deltaColor.b * dt); int a = Color.alpha(p.color) + (int) (p.deltaColor.a * dt); p.color = Color.argb(a, r, g, b); // size p.size += (p.deltaSize * dt); p.size = Math.max(0, p.size); // angle p.rotation += (p.deltaRotation * dt); // update particle counter ++mParticleIdx; } else { // life < 0 if (mParticleIdx != mParticleCount - 1) { mParticles[mParticleIdx].copy(mParticles[mParticleCount - 1]); } --mParticleCount; } } // while if (needInvalidate && null != mCallbackRef) { UpdateCallback callback = mCallbackRef.get(); if (null != callback) { callback.needInvalidate(); } } } postStep(); }
// ! Initializes a particle protected void initParticle(Particle particle) { // timeToLive // no negative life. prevent division by 0 particle.timeToLive = mLife + mLifeVar * randomMinus1To1(); particle.timeToLive = Math.max(0, particle.timeToLive); // position particle.pos.x = mSourcePosition.x + mPosVar.x * randomMinus1To1(); particle.pos.y = mSourcePosition.y + mPosVar.y * randomMinus1To1(); // Color int start; int r = Misc.clamp( Color.red(mStartColor) + (int) (Color.red(mStartColorVar) * randomMinus1To1()), 0, 255); int g = Misc.clamp( Color.green(mStartColor) + (int) (Color.green(mStartColorVar) * randomMinus1To1()), 0, 255); int b = Misc.clamp( Color.blue(mStartColor) + (int) (Color.blue(mStartColorVar) * randomMinus1To1()), 0, 255); int a = Misc.clamp( Color.alpha(mStartColor) + (int) (Color.alpha(mStartColorVar) * randomMinus1To1()), 0, 255); start = Color.argb(a, r, g, b); int end; r = Misc.clamp( Color.red(mEndColor) + (int) (Color.red(mEndColorVar) * randomMinus1To1()), 0, 255); g = Misc.clamp( Color.green(mEndColor) + (int) (Color.green(mEndColorVar) * randomMinus1To1()), 0, 255); b = Misc.clamp( Color.blue(mEndColor) + (int) (Color.blue(mEndColorVar) * randomMinus1To1()), 0, 255); a = Misc.clamp( Color.alpha(mEndColor) + (int) (Color.alpha(mEndColorVar) * randomMinus1To1()), 0, 255); end = Color.argb(a, r, g, b); particle.color = start; r = (int) ((Color.red(end) - Color.red(start)) / particle.timeToLive); g = (int) ((Color.green(end) - Color.green(start)) / particle.timeToLive); b = (int) ((Color.blue(end) - Color.blue(start)) / particle.timeToLive); a = (int) ((Color.alpha(end) - Color.alpha(start)) / particle.timeToLive); particle.deltaColor = new Colour(a, r, g, b); // size float startS = mStartSize + mStartSizeVar * randomMinus1To1(); startS = Math.max(0, startS); // No negative value particle.size = startS; if (mEndSize < 0) { particle.deltaSize = 0; } else { float endS = mEndSize + mEndSizeVar * randomMinus1To1(); endS = Math.max(0, endS); // No negative values particle.deltaSize = (endS - startS) / particle.timeToLive; } // rotation float startA = mStartSpin + mStartSpinVar * randomMinus1To1(); float endA = mEndSpin + mEndSpinVar * randomMinus1To1(); particle.rotation = startA; particle.deltaRotation = (endA - startA) / particle.timeToLive; if (mPositionType == PositionType.POSITION_GROUP) { particle.startPos = new Point(); } else { particle.startPos = new Point(mPosition); } // direction double radians = Math.toRadians(mAngle + mAngleVar * randomMinus1To1()); // Mode Gravity: A if (mEmitterMode == EmitterMode.MODE_GRAVITY) { Point v = new Point((float) Math.cos(radians), (float) Math.sin(radians)); float s = modeA.speed + modeA.speedVar * randomMinus1To1(); // direction particle.modeA.dir = Point.mult(v, s); // radial accel particle.modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * randomMinus1To1(); // tangential accel particle.modeA.tangentialAccel = modeA.tangentialAccel + modeA.tangentialAccelVar * randomMinus1To1(); } else { // Mode Radius: B // Set the default diameter of the particle from the source position float startRadius = modeB.startRadius + modeB.startRadiusVar * randomMinus1To1(); float endRadius = modeB.endRadius + modeB.endRadiusVar * randomMinus1To1(); particle.modeB.radius = startRadius; if (modeB.endRadius < 0) { particle.modeB.deltaRadius = 0; } else { particle.modeB.deltaRadius = (endRadius - startRadius) / particle.timeToLive; } particle.modeB.angle = a; particle.modeB.degreesPerSecond = (float) Math.toRadians(modeB.rotatePerSecond + modeB.rotatePerSecondVar * randomMinus1To1()); } }
public void setPosVar(Point var) { mPosVar.set(var.x, var.y); }
public void setSourcePosition(Point var) { mSourcePosition.set(var.x, var.y); }
public void setPosition(float x, float y) { mPosition.set(x, y); }