public void draw(Graphics2D g2d) {
   AffineTransform saved = g2d.getTransform();
   Iterator<Zombie> it = this.zombiesAlive.iterator();
   while (it.hasNext()) {
     Zombie z = it.next();
     z.draw(g2d);
     g2d.setTransform(saved);
   }
 }
 public void checkPlayerDamage(Player player) {
   Iterator<Zombie> it = this.zombiesAlive.iterator();
   while (it.hasNext()) {
     Zombie z = it.next();
     if (!player.hasEffect(Invulnerability.EFFECT_NAME)) {
       if (player.intersects(z.getRect())) player.takeDamage(z.getDamage());
       if (z.getParticles() != null) {
         Iterator<Particle> pit = z.getParticles().iterator();
         while (pit.hasNext()) {
           Particle p = pit.next();
           if (p.checkCollision(player)) player.takeDamage(z.getParticleDamage());
         }
       }
     }
   }
 }
  public void update(Player player, ItemFactory itemFactory) {
    // Remove dead zombies from the live list.
    if (!this.zombiesToDie.isEmpty()) this.zombiesAlive.removeAll(this.zombiesToDie);
    // If the spawn timer is up, spawn a new zombie.
    if (!this.zombiesUnborn.isEmpty()
        && (Globals.gameTime.getElapsedMillis() >= this.nextZombieSpawn)) {
      Zombie z = this.zombiesUnborn.remove(0);
      if (z.getType() == Globals.ZOMBIE_MATRON_TYPE)
        z.set(0, (Globals.gameTime.getElapsedMillis() + ZombieMatron.TIME_TO_BURST));
      this.zombiesAlive.add(z);
      this.nextZombieSpawn = Globals.gameTime.getElapsedMillis() + ZombieWave.ZOMBIE_SPAWN_TIME;
    }
    if (!this.zombiesUnborn.isEmpty()) {
      // If there are any tiny zombies in the list, add them all at once.
      Iterator<Zombie> it = this.zombiesUnborn.iterator();
      while (it.hasNext()) {
        Zombie z = it.next();
        if (z.getType() == Globals.ZOMBIE_TINY_TYPE) {
          this.zombiesAlive.add(z);
          it.remove();
        }
      }
    }
    // Update "living" zombies.
    Iterator<Zombie> it = this.zombiesAlive.iterator();
    while (it.hasNext()) {
      Zombie z = it.next();

      { // Handle the zombie's movement and animation.
        // Update the zombie's animation.
        z.getImage().update();

        // Update the zombie.
        double theta_ =
            Math.atan2((player.getCenterY() - z.y), (player.getCenterX() - z.x)) + Math.PI / 2;
        z.rotate(theta_);
        z.move(theta_);
        z.update(player, this.zombiesUnborn);
        z.moan(player);
      } // End movement and animation updates.
      { // Check the zombie for collisions with ammo, etc.
        if (!z.isDead()) {
          // Check for collisions with ammo, etc.
          // Iterator<Weapon> wit = player.getAllWeapons().iterator();
          Iterator<Weapon> wit = player.getWeaponsMap().values().iterator();
          while (wit.hasNext()) {
            Weapon w = wit.next();
            int damage = w.checkForDamage(z.getRect());
            if (player.getDamageBonus() > 0) damage += (damage * player.getDamageBonus());
            if (damage > 0) {
              z.takeDamage(damage);
              if (z.isDead()) {
                // Give the player some cash.
                player.addCash(z.getCashValue());
                player.addExp(z.getExpValue());
                player.addKill();
                if (z.getType() >= 3) {
                  // Base chance of 10% (19-20) to drop a powerup.
                  // 10% extra for each tier of zombie.
                  int dropRoll = Globals.r.nextInt(20) + 1;
                  if ((z.getType() >= Globals.ZOMBIE_ACID_TYPE)
                      && (z.getType() < Globals.ZOMBIE_TINY_TYPE))
                    dropRoll += (z.getType() % Globals.ZOMBIE_ACID_TYPE) * 2;
                  if (dropRoll >= 19) {
                    SpeedUp speed = new SpeedUp(z);
                    UnlimitedAmmo unlimited = new UnlimitedAmmo(z);
                    ExtraLife extra = new ExtraLife(z);
                    ExpMultiplier exp = new ExpMultiplier(z);
                    Invulnerability invuln = new Invulnerability(z);
                    NightVision night = new NightVision(z);
                    Item[] statusItems = {
                      speed, unlimited, night, speed, invuln, speed, extra, speed, exp, speed,
                      night, exp, night
                    };
                    int i = Globals.r.nextInt(statusItems.length);
                    itemFactory.dropItem(statusItems[i]);
                  }
                }
              }
            }
          }
        }

        // Check again, and if the zombie is dead, add to the toDie list.
        if (z.isDead()) this.zombiesToDie.add(z);
      } // End checking zombie for death.
    }
  }