Вы попали в ловушку, решив, что каждое существительное должно быть классом, а не каждый класс должен быть классом. Обычно люди с этим синдромом создают класс для каждого существительного в своей программе — Игрок, Оружие, Уровень — но вы, кажется, вместо этого взяли свои существительные из телевизионной игры в спортивный мяч — Рефери, Аудиоинженер, Диктор. Я не совсем уверен, откуда у вас появилась эта идея.
Как бы то ни было, «создать класс для каждого существительного», как правило, плохой совет. Да, классы — это существительные, грубо говоря, но вы все равно хотите использовать их, когда они полезны, и не использовать их, когда они бесполезны, как и все остальное. Вы не делаете его по привычке только потому, что где-то видите существительное.
Вы это сделали, и теперь вы не знаете, что делать со всеми этими бесполезными классами, не имеющими реального значения.
Мое предложение: удалите их (вы можете сохранить код) и подумайте о том, что вы хотите, чтобы компьютер делал, а затем реализуйте это. Вы не хотите, чтобы компьютер притворялся аудиоинженером — вы хотите, чтобы он воспроизводил звук.
В играх нередко получается большой «божественный класс», который включает в себя множество игровой логики. Это похоже на ваш класс рефери. ИМО, это признак того, что код вообще не должен быть в каком-либо классе, но вы используете язык, который все равно заставляет вас помещать его в класс.
Вы все равно должны использовать другие классы, где это имеет смысл. Вы можете сделать окно чата отдельной вещью, так как это не имеет никакого отношения к игровому процессу. Вы можете сделать состояние игры (подготовка, работа, завершение) отдельной вещью, в зависимости от того, что это означает для вашей игры. На самом деле, ваш менеджер состояния игры (турнир?) может просто new
начинать новую игру (раунд?) каждый раз, когда он хочет ее запустить.
Для вашей проблемы со звуком есть соответствующий шаблон, который является шаблоном наблюдателя (также называемым слушателем). Вы можете создать интерфейс наподобие GunshotListener, а затем ваш код выстрела (в зависимости от того, в каком классе он находится) содержит список ссылок на GunshotListeners. Когда игрок стреляет из пистолета, код выстрела делает что-то вроде for(gsl in gunshotListeners) {gsl.onGunShot(player, coordinates);}
С практической точки зрения, может быть, это слишком специфично, потому что в вашей игре происходит 200 вещей, а 200 разовых классов слушателей — это слишком много. Возможно, вам лучше использовать SoundEffectListener, и это будет for(sel in soundEffectListeners) {sel.onSoundEffect(coordinates, GUNSHOT_SOUND_EFFECT);}
Затем при создании игры вы создадите сетевую звуковую систему (а также все остальное, например, систему чата) и зарегистрируете ее в качестве слушателя, добавив ее в список. Если вам нужна другая звуковая система, вы можете добавить ее вместо нее, а если вам не нужна звуковая система, вы можете просто не добавлять ее.
Лично я (и это может быть спорным) я бы разместил код огнестрельного оружия там, где это наиболее удобно для вашей игры. Стрельба - это не то, что делает оружие. В реальной жизни оружие стреляет, но в компьютерной жизни компьютер вычисляет точность сканирования на основе типа оружия, формы уровня и местоположения других игроков, и оружие в этом процессе на самом деле не очень важно. Возможно, если оружие в вашей игре полностью отличается друг от друга, то имеет смысл поместить его в класс оружия, чтобы его можно было переопределить для каждого типа оружия. Опять же, возможно, нет. Многие игры поместили бы этот код в класс основной игры, класс уровня (потому что он обращается к геометрии уровня) или GunshotCalculator.
Я не понимаю, зачем вам нужно что-то особенное, называемое рефери. Игрок не может обмануть, загрузив свой собственный класс оружия, верно? Я надеюсь, что они не могут, так как они могут загрузить класс оружия, который форматирует жесткий диск сервера, когда он стреляет. Итак, вы знаете, что делают пушки, и вы знаете, что они не позволяют обманывать, потому что вы не писали код, чтобы заставить их обманывать, поэтому вам не нужен дополнительный класс, чтобы убедиться, что они не обманывают.
Прикрепляю к посту несколько видео по теме: