Доступность игр на pygame

от автора

Всем привет.

В статье Звуковые игры: невидимый рынок ждёт героев были рассмотрены звуковые игры с крутым объемным звуком, и библиотеки для его создания.

Ну а я решил начать с малого, и для начала организовать озвучивание синтезатором действий в пошаговых играх на pygame.

Конечно не для всех игр подходит такой прием, но в некоторых очень даже.

Создадим модуль speech.

В нем организуем два варианта работы:

  • подключение к экранному диктору NVDA через его Controller dll;
  • напрямую на синтезатор windows через SAPI5;

Сначала импортируем все необходимые модули.
Для подключения nvdaControllerClient32.dll нам нужен ctypes.

import ctypes

А при отсутствии NVDA на компьютере, работаем напрямую с синтезатором SAPI через win32api.

import win32com.client

Создаем класс для нашей говорилки.

class Speech:      def __init__(self, config):         """Initialize speech class."""         self.config = config 

Здесь наверно надо пояснить про config. В общем классе Game, который занимается инициализацией всех модулей игры и крутит основной цикл, идет загрузка настроек игры.

Настройки можно загружать откуда удобнее: ini файлы, json, sqlite, или любой другой удобный вариант.

Но продолжим инициализацию нашего Speech.

        # подключаем синтезатор как COM объект.         self.speaker = win32com.client.Dispatch("Sapi.SpVoice")         # Получаем все доступные синтезаторы в системе и сохраняем в списке         self.voices = self.speaker.GetVoices()         # Создаем список имен полученных голосов         self.voices_names = [voice.GetDescription() for voice in self.voices] 

Настроим подключенный синтезатор некоторыми параметрами из настроек.
В данном примере я беру просто индекс установленного голоса (установленный по умолчанию имеет индекс 0), но можно сделать настройки с выбором из выпадающего списка по имени, полученных как описывалось выше.

Скорость голоса устанавливается в диапозоне от -10 до +10. Но не думаю, что кто-то захочет слушать голос со скоростью ниже 5. Можете самостоятельно поэкспериментировать, меняя значение в настройках.

Ну и конечно громкость голоса. Тут стандартно от 0 до 100.

        self.set_voice(self.config.voice)         self.speaker.Rate = self.config.rate         self.speaker.Volume = self.config.volume 

Ну и наконец инициализируем nvda.

        self.nvda = self.config.nvda         self.nvda_error = False         self.sLib = ctypes.windll.LoadLibrary('./nvdaControllerClient32.dll') 

Сразу проверяем может ли наша программа подключиться к работающей программе NVDA.

        nvda_error = self.sLib.nvdaController_testIfRunning()         errorMessage = str(ctypes.WinError(nvda_error))         if 0 != nvda_error:             print('NVDA error: ' + errorMessage)             self.nvda_error = True 

После того как проинициализировали и синтезатор SAPI, и nvda dll можно запустить функцию выбора аудио вывода речи.

        self.set_speak_out()         

Добавим функцию установки голоса из списка доступных по индексу.

    def set_voice(self, index):         """Set voice for speak."""         try:             self.speaker.Voice = self.voices[index]             self.speak_sapi(self.voices_names[index])         except:             print('error: do not set voice') 

А теперь функция по выбору аудио вывода речи. Тут мы собственно и выбираем, что будем использовать для работы: nvda или синтезатор напрямую.

Выбор заключается в двух параметрах:

  • Флаг в настройках, хочет ли пользователь вообще чтоб игра использовала NVDA;
  • Возможные ошибки при подключении к NVDA;

    def set_speak_out(self):         """Set speak out: nvda or sapi."""         if self.nvda and not self.nvda_error:             self.speak = self.speak_nvda         else:             self.speak = self.speak_sapi 

Ну и конечно пропишем функции произношения.

Для NVDA:

    def speak_nvda(self, phrase):         self.sLib.nvdaController_speakText(phrase) 

А это функция для произношения напрямую на синтезатор:

    def speak_sapi(self, phrase):         self.speaker.Speak(phrase) 

Вот и все. Теперь в любом месте игровой логики отправляем нужную информацию на speech.speak().

Надеюсь данная статья кому-то окажется полезной и будет появляться больше доступных игр.


ссылка на оригинал статьи https://habr.com/post/424477/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *