@Override public void run() { running = true; messages.write("Defend your home planet!", 500); messages.write("Press O and D to set research focus.", 600); while (true) { if (!running) { setChanged(); notifyObservers(); try { Thread.sleep(DELAY); } catch (InterruptedException e) { System.out.println("Interrupted."); return; } continue; } synchronized (this) { research.step(); /* Shoot the weapon. */ if (firing) { long now = System.currentTimeMillis(); long diff = now - lastFire; if (diff >= weapon.getSpeed()) { shots.add(weapon.fire(fireX, fireY)); lastFire = now; } } /* Spawn meteoroids. */ danger += difficulty; double spawn = danger; while (spawn > 0) { if (RNG.nextFloat() < danger) { double d = SIDE / 2d * Math.sqrt(2); double a = RNG.nextDouble() * Math.PI * 2; double x = Math.cos(a) * d; double y = Math.sin(a) * d; meteoroids.add(new Meteoroid(x, y)); } spawn -= 1d; } /* Step debris forward. */ Set<Debris> old = new HashSet<Debris>(); for (Debris d : debris) { d.step(); if (d.getTTL() <= 0f) { old.add(d); } } debris.removeAll(old); /* Step meteoroids forward. */ Set<Meteoroid> dead = new HashSet<Meteoroid>(); for (Meteoroid m : meteoroids) { if (m.step(home)) { dead.add(m); home.absorb(m); m.setAlive(false); } } /* Step weapon shots forward. */ Set<Shot> spent = new HashSet<Shot>(); for (Shot s : shots) { Meteoroid m = s.step(this); if (m != null && !dead.contains(m)) { dead.add(m); m.setAlive(false); s.setAlive(false); debris.addAll(m.breakup()); score += m.getSize(); } else if (s.getDistance() > SIDE) { spent.add(s); } } shots.removeAll(spent); meteoroids.removeAll(dead); /* Manage incoming and outgoing objects. */ while (outgoing.peek() != null) { SpaceObject o = outgoing.poll(); if (o instanceof Shot) { shots.remove((Shot) o); } else if (o instanceof Meteoroid) { meteoroids.remove((Meteoroid) o); } else if (o instanceof Debris) { debris.remove((Debris) o); } } while (incoming.peek() != null) { SpaceObject o = incoming.poll(); if (o instanceof Shot) { shots.add((Shot) o); } else if (o instanceof Meteoroid) { meteoroids.add((Meteoroid) o); } else if (o instanceof Debris) { debris.add((Debris) o); } } /* Check game over status. */ if (home.getHealth() <= 0) { System.out.println("Game over"); running = false; meteoroids.clear(); shots.clear(); debris.clear(); } } setChanged(); notifyObservers(); try { Thread.sleep(DELAY); } catch (InterruptedException e) { System.out.println("Interrupted."); return; } } }