Exemplo n.º 1
0
  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();
  }