Доступность игр на 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().

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

Средняя зарплата в IT

110 450 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 7 043 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 13

    +1
    Хорошее дело делаете! Пока не прочитаешь о таком, даже не задумаешься что кому-то необходимо что-то такое.

    Только вот заголовок слегка вводит в заблуждение — я открывал статью чтобы посмотреть список игр на pygame и их успешности на рынке.
      0
      Спасибо большое за ваше мнение.
      А насчет заголовка. Я тоже думал сменить pygame на что-то более подходящее, но не смог подобрать более подходящее определение. хотелось указать отношение к python, и игры на pygame просто оказались самым подходящим для данного модуля. Может кто-то предложит другое удачное применение, буду только рад.
      0
      Я бы советовал для всего этого использовать библиотеку Tolk, которая реализует общую обёртку API речевого вывода. Она автоматически проверяет наличие программы экранного доступа (в порядке: JAWS, Window-Eyes, NVDA, SuperNova, System Access, ZoomText) и при обнаружении запущенного экземпляра программы отправляет текст на вывод через её API, ну а если ни одной из поддерживаемых программ не обнаружено, то может выполнить речевой вывод через Microsoft Speech API 5.

      В отличие от вашей реализации, с Tolk вы получите более универсальное решение с поддержкой существенно большего числа программ экранного доступа, а также с поддержкой брайлевского вывода (где это возможно). Ну и всё это без необходимости собственноручно реализовывать и унифицировать поддержку всех API программ через их специальные dll и com-объекты, а просто одним вызовом.
        0
        Спасибо за информацию, не знал о такой библиотеки. Просто тут есть два момента:
        1. Данный модуль я писал в целях попробовать работу с windows SAPI5;
        2. данная библиотека хороша для больших проектов, а для тех простеньких логических игр, что я писал, необходимость ее компиляции как-то слишком сложна, по сравнению с десятком несложных строк кода.
        Да и поддержкой брайлевского вывода для игр как-то сомнительно, но может быть конечно где-то наверно.
        Как говорится: простое лучше сложного :)
        Но библиотека конечно интересная, спасибо, обязательно посмотрю.
          0
          Тут следует учитывать, что NVDA всё же не единственная программа экранного доступа и даже не являющаяся по распространённости абсолютным лидером, поэтому поддержка других программ довольно актуальна. Вывод через SAPI5 для самоозвучивающихся интерфейсов является альтернативой, но не равноценной, потому что, например, фразу, произносимую через API самого screenreader'а, пользователь при необходимости может прервать, поставить на паузу, перечитать в истории произнесённых фраз и так далее, а речевой вывод через SAPI5 не такой гибкий в этом отношении, там, в частности, без специальной нетривиальной доработки всего механизма чтения придётся дослушивать до конца все фразы, даже если хочется прервать. Поэтому если есть такая возможность, то предпочтительнее использовать API программы экранного доступа. Tolk поможет с минимальными трудозатратами получить поддержку наиболее распространённых программ и в итоге обеспечить наиболее удобное решение для конечного пользователя. Впрочем, некоторые интерфейсные доработки в самой игре также не помешают, в частности, клавиатурная команда для повторного произнесения фразы с описанием.

          В качестве примеров использования вывода через Tolk, а также ещё ряда других технических приёмов обеспечения невизуальной доступности, можно посмотреть на интерпретаторы текстовых игр TadsWrapper и PlainInsteat. Там реализованы и дополнительные вещи, типа фокусируемого с клавиатуры поля текстового вывода, но что касается быстрого озвучивания, то это реализовано как раз так, как лучше всего делать: при изменении описания автоматический вывод через Tolk с поддержкой большого числа программ, плюс по горячей клавиши прочтение можно повторить.

          Кстати, если уже есть готовые игры с обеспеченной невизуальной доступностью, то можете подписаться на список рассылки по компьютерным играм для незрячих и закинуть туда ссылки, чтобы донести их до целевой аудитории.
            0
            В API SAPI5 тоже есть возможность прервать воспроизводимую фразу, поставить на паузу и затем продолжить, просто я не реализовывал данный функционал в этом модуле, так как для моих проектов не было в этом необходимости, но можно легко добавить. Но то что работа через screenreader`ы гораздо гибче — я с вами полностью согласен. Поэтому и писал спасибо за ссылку на интересную библиотеку, обязательно попробую.
            А насчет поделиться с сообществом, конечно. Я опубликовал их, и дальнейшие буду публиковать, на blind.games, и обязательно подпишусь и добавлю в рассылку по вашей ссылке. Спасибо.
              0
              Попробовал библиотеку tolk, которую вы приводили. ScreenReader NVDA подхватила и работает, а вот без screenreader`а на SAPI5 синтезатор ничего не вывела. Похоже она поддерживает множество скринридеров, но sapi не сделан, или с ним надо работать как-то по другому чем со скринридерами.
              Также скачал TadsWrapper 6, хотел попробовать, но, к сожалению, ничего не вышло. Так и не смог запустить на моей windows 8.1. Режим совместимости с windows 7 тоже не помог.
              Есть ли какие-то рекомендации по запуску, или обсуждение где-то?
              На рассылку подписался и отправил первые пробные проекты :)
                0
                По умолчанию вывод через SAPI5 отключён: «By default, support for SAPI is disabled. To change this, use Tolk_TrySAPI, passing true to enable SAPI or false to disable it.»
                Зрячим, как правило, произнесение вслух не нужно, поэтому это чаще лишняя функция, если речь идёт об интерфейсе в универсальном дизайне (один для всех пользователей).
                Правда есть вполне реальная ситуация, когда пользователь работает со встроенным screenreader'ом Windows Экранный диктор (Narrator) или ещё каким-нибудь, типа COBRA, у которых соответствующих API нет, так что Tolk они не поддерживаются. Статистически это не очень большая доля целевой аудитории, но она существует. Здесь как раз вывод через SAPI5 будет уместен. Этот конфликт интересов незрячего пользователя, работающего с неподдерживающимся напрямую screenreader'ом, и зрячего пользователя надо разруливать разработчику, например, вводить настройку чтения вслух или игнорировать какую-то из проблем.

                Что касается TadsWrapper, то я затрудняюсь посоветовать что-то определённое без подробностей. В чём именно проявляется невозможность запуска?
                Если что, запускать надо файл TadsWrapper.exe и у меня на Windows 7 и Windows 10 (как x86, так и x64) никаких проблем не воспроизводится. Windows 8.1 под рукой, к сожалению, нет, но вряд ли там могут быть какие-то специфические особенности именно на уровне OS. Возможно конфликт с антивирусом, хотя до этого момента ни одного такого случая, насколько мне известно, не было.
                  0
                  Вот этот момент с отключенным SAPI по умолчанию как-то упустил. Спасибо за развернутый ответ, интересная библиотека, буду использовать :)
                  Насчет TadsWrapper.
                  На одном компьютере выкидывает сообщение:
                  «Не удается запустить приложение, так как его параллельная конфигурация не правильна. Дополнительные сведения в журнале приложений.»
                  А на другом компе, но тоже с windows 8.1 приложение просто блокируется защитником windows и все.
                  Антивирус не установлен, так что дело не в нем.
                    0
                    Обсудил с основным разработчиком и вроде всплыл какой-то тонкий момент с разрядностями библиотек при сборке. Уточните, на системе с какой разрядностью у вас проблемы с TadsWrapper?
                      0
                      Разрядность обоих windows 64.
                      А TadsWrapper скачал тот, что был выложен в той рассылке, которую вы привели в комментариях выше.
                        0
                        Если вам это ещё актуально, то после некоторых исследований выяснилось, что TadsWrapper 6 для корректной работы требуется Распространяемый пакет среды выполнения Microsoft Visual C++ 2008. Упомянутая выше ошибка возникает из-за того, что по умолчанию этих библиотек в систему не установлено. Надо, конечно, побороться за автономность, но пока недостающие библиотеки можно установить вручную (32-разрядная версия и 64-разрядная версия). Для 64-разрядных систем, скорей всего, потребуется установить оба пакета.
                          0
                          Ну чего же не актуально, актуально конечно. Спасибо вам за исследования и информацию. Обязательно скачаю библиотеки и попробую :)

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое