Ich hab mir deine Klassen mal angesehen und ein paar Punkte sind mir aufgefallen, die man besser lösen könnte/sollte:
Ball:
1) Du erzeugst mit jedem Ball ein neues Random-Objekt. Effektiver wäre es, ein einzelnes statisches Random-Objekt für alle Bälle zu erzeugen und das zu benutzen.
2) Zur Bewegung des Balls kann man hervorragend Vektoren benutzen; das Ganze wird dadurch viel allgemeiner anwendbar und vor allem einfacher zu kontrollieren.
3) Bälle, die sich diagonal bewegen, haben eine um sqrt(2) höhere Geschwindigkeit als Bälle, die sich gerade bewegen, weil sie sich mit jedem Zeitschritt um 1 * speed in x- und um 1* speed in y-Richtung bewegen. Zur Lsöung kann man gut Punkt 2) benutzen, wenn man den Vektor normiert.
Game:
1) Eventuell könnte man lives, die streak-Variablen und combo in eine eigene Player-Klasse (oder etwas in der Art) auslagern. Ist aber mehr Kosmetik als wirklich nützlich, wenn du das Projekt nicht weiterführen willst.
2) Der sleep(10)-Aufruf nach jedem Update aller Objekte zerstört das Konzept der konstanten Berechnung; die Zeit, die sleep() verwenden sollte, sollte doch eigentlich von der Zeit abhängen, die der letzte Durchgang des Loops benötigt hat, oder?
(Siehe hier, letzter Absatz:
Klick mich)
3) Immer, wenn du einen neuen Ball erzeugst und seine nächste Position ermittelst, erzeugst du ein neues Random-Objekt. Ein Random-Objekt für alle ist da sicherlich ausreichend.
GameWin:
1) Arena der Übersicht halber in eine eigene Datei auslagern.
2) In jedem update() wird unnötigerweise das Observable zu Game gecastet, nur um balls die selbe Referenz noch einmal zuzuweisen. Wenn du das schon bei der Initialisierung eines neuen Games machst, sparst du dir den Cast und die Zuweisung - nicht viel, aber immerhin etwas.
Zu den Bildern: persönlich würde ich eher zu .png tendieren denn zu .jpg, weil .jpg durch die Kompirmierung verzerrt und unscharf werden kann.
Ansonsten ordentlich gemacht, vielleicht noch einen schönen Hintergrund einbauen und den Bällen mehr Tiefe verleihen (Glanzeffekt etc.; dementsprechend über Bilder arbeiten?). Wenn du noch irgendwo eine Animation einbaust, kannst du das gleich noch üben und andere haben eine weitere nützliche Vorlage, wenn sie sich in dieses gar nicht so einfache Gebiet hineinwagen.
Auch ein paar besondere Effekte oder Upgrades etc. wären noch ganz schön; auf die Schnelle fällt mir ein Powerup ein, dass beim Abschießen die Zeit für ein paar Sekunden verlangsamt und eins, das für kurze Zeit alle Bälle größer macht.
Besonderen Wert würde ich bei zukünftigen Optimierungen immer auf die Methoden legen, die besonders oft aufgerufen werden: das wären hier natürlich die verschiedenen update()-Methoden sowie der Konstruktor für die Bälle.
EDIT: außerdem ruckeln und flickern (zumindest bei mir) die schnelleren Bälle. Double Buffering hilft hier.