Статические методы класса как раз для оперирования с несколькими экземплярами класса?
Статические поля и методы служат для работы с классом в целом. Примеры:
• Есть десять объектов и новых создавать нельзя.
• Общий для всей проги объектный пул, а второго, скорее всего, не будет.
• Псевдоконструктор — Rect.xyxy(x1,y1,x2,y2) и Rect.xywh(x,y,w,h).
• Функциональность никак не зависит от экземпляра объекта: calculateDamageWithCrit при условии, что генератор случайных чисел тоже статический (принадлежит библиотеке языка в целом, а не игровому миру).
Где правильно хранить экземпляры классов врагов?
С Wave вы, вероятно, сами запутались: это то информация о волне, то часть текущего состояния мира. Я бы всех врагов закинул в Game (правда, назвал бы объект World).
Создать статическую переменную в классе башни, или все же создать экземпляр башни и хранить его в классе игры
Башня принадлежит игровому миру — тоже её в Game (или World).
У башни есть массив с пулями которые она выпускает.
Пули очень не стоит в башню — их лучше в тот же Game/World. Башню вы уничтожаете — пули тоже исчезают?
И эта вот функция просчёта у меня просто в файле. Нужно ли её загонять в класс как метод?
Только для красоты. Не важно, где лежит скрытая функция, если она не зависит от экземпляра (типа-статическая) и скрытая (не видна снаружи).
Важная штука: часто в играх есть неизменная информация о врагах, башнях, пулях (TowerType, EnemyType, BulletType, WaveInfo…), и есть конкретный экземпляр (Tower, Enemy, Bullet). Иногда враги, башни и пули объединяют в один GameObj, но это уже зависит от архитектуры. Возможно и так, и этак.