public void emit() {
    for (int i = 1; i <= emitNum; i++) {
      Particle x = new Particle(loc.x, loc.y, 0, null);
      if (images != null) {
        x.setImage(images[(int) randomP(images.length)]);
      } else {
        x.setImage(null);
      }
      double temp = angle2 - angle1;
      double newAngle = (((rnd.nextDouble() * temp) + angle1) * Math.PI / 180);
      if (randomV) {
        x.setVel(
            randomP(xSpeed) * FastMath.cos(newAngle), randomP(ySpeed) * FastMath.sin(newAngle), 0);
      } else {
        x.setVel(xSpeed * FastMath.cos(newAngle), ySpeed * FastMath.sin(newAngle), 0);
      }

      x.setFade(fade);
      x.setFadeRate(fadeRate);
      x.setLoc(loc.x + random(spreadX), loc.y + random(spreadY), 0);
      x.setAcc(xAcc, yAcc, 0);
      x.setMaxAge(maxAge);
      x.setMaxSize(maxSize);
      x.setSize(size);
      x.setAgeRate(ageRate);
      x.setGrowthRate(growthRate);
      x.setBlink(blink);
      x.setColor(color);
      x.setMaxSpeed(new Vector3D(maxXSpeed, maxYSpeed, 0));
      particleManager.addParticle(x);
    }
  }
  /**
   * @see
   *     org.newdawn.slick.particles.ParticleEmitter#updateParticle(org.newdawn.slick.particles.Particle,
   *     int)
   */
  @SuppressWarnings("null")
  @Override
  public void updateParticle(Particle particle, int delta) {
    particleCount++;

    // adjust the particles if required
    particle.x += adjustx;
    particle.y += adjusty;

    particle.adjustVelocity(
        windFactor.getValue(0) * 0.00005f * delta, gravityFactor.getValue(0) * 0.00005f * delta);

    float offset = particle.getLife() / particle.getOriginalLife();
    float inv = 1 - offset;
    float colOffset = 0;
    float colInv = 1;

    Color startColor = null;
    Color endColor = null;
    for (int i = 0; i < colors.size() - 1; i++) {
      ColorRecord rec1 = colors.get(i);
      ColorRecord rec2 = colors.get(i + 1);

      if ((inv >= rec1.pos) && (inv <= rec2.pos)) {
        startColor = rec1.col;
        endColor = rec2.col;

        float step = rec2.pos - rec1.pos;
        colOffset = inv - rec1.pos;
        colOffset /= step;
        colOffset = 1 - colOffset;
        colInv = 1 - colOffset;
      }
    }

    if (startColor != null) {
      float r = (startColor.r * colOffset) + (endColor.r * colInv);
      float g = (startColor.g * colOffset) + (endColor.g * colInv);
      float b = (startColor.b * colOffset) + (endColor.b * colInv);

      float a;
      if (alpha.isActive()) a = alpha.getValue(inv) / 255.0f;
      else
        a = ((startAlpha.getValue(0) / 255.0f) * offset) + ((endAlpha.getValue(0) / 255.0f) * inv);
      particle.setColor(r, g, b, a);
    }

    if (size.isActive()) {
      float s = size.getValue(inv);
      particle.setSize(s);
    } else particle.adjustSize(delta * growthFactor.getValue(0) * 0.001f);

    if (velocity.isActive()) particle.setSpeed(velocity.getValue(inv));

    if (scaleY.isActive()) particle.setScaleY(scaleY.getValue(inv));
  }
  /**
   * @see
   *     org.newdawn.slick.particles.ParticleEmitter#update(org.newdawn.slick.particles.ParticleSystem,
   *     int)
   */
  @Override
  public void update(ParticleSystem system, int delta) {
    this.engine = system;

    if (!adjust) {
      adjustx = 0;
      adjusty = 0;
    } else adjust = false;

    if (updateImage) {
      updateImage = false;
      try {
        image = new Image(relativePath + imageName);
      } catch (SlickException e) {
        image = null;
        Log.error(e);
      }
    }

    if (((wrapUp)
            || ((length.isEnabled()) && (timeout < 0))
            || ((emitCount.isEnabled() && (leftToEmit <= 0))))
        && (particleCount == 0)) {
      completed = true;
    }
    particleCount = 0;

    if (wrapUp) return;

    if (length.isEnabled()) {
      if (timeout < 0) return;
      timeout -= delta;
    }
    if (emitCount.isEnabled() && leftToEmit <= 0) return;

    nextSpawn -= delta;
    if (nextSpawn < 0) {
      nextSpawn = (int) spawnInterval.random();
      int count = (int) spawnCount.random();

      for (int i = 0; i < count; i++) {
        Particle p = system.getNewParticle(this, initialLife.random());
        p.setSize(initialSize.random());
        p.setPosition(x + xOffset.random(), y + yOffset.random());
        p.setVelocity(0, 0, 0);

        float dist = initialDistance.random();
        float power = speed.random();
        if ((dist != 0) || (power != 0)) {
          float s = spread.getValue(0);
          float ang = (s + angularOffset.getValue(0) - (spread.getValue() / 2)) - 90;
          float xa = (float) FastTrig.cos(Math.toRadians(ang)) * dist;
          float ya = (float) FastTrig.sin(Math.toRadians(ang)) * dist;
          p.adjustPosition(xa, ya);

          float xv = (float) FastTrig.cos(Math.toRadians(ang));
          float yv = (float) FastTrig.sin(Math.toRadians(ang));
          p.setVelocity(xv, yv, power * 0.001f);
        }

        if (image != null) p.setImage(image);

        ColorRecord start = colors.get(0);
        p.setColor(start.col.r, start.col.g, start.col.b, startAlpha.getValue(0) / 255.0f);
        p.setUsePoint(usePoints);
        p.setOriented(useOriented);

        if (emitCount.isEnabled()) {
          leftToEmit--;
          if (leftToEmit <= 0) break;
        }
      }
    }
  }