Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.

Перейти к содержимому раздела

Blind games - Звуковые игры незрячим

Форум сайта "blind.games". Добро пожаловать.

Архивный режим

Форум переводится в архивный режим. Это значит, что все учетные записи, темы и сообщения остаются на момент 19.07.2018, а добавлять новые уже нельзя. То есть, закрыта регистрация, добавлен запрет на создание новых тем и ответы в существующих.
По всем вопросам, как и ранее, вы можете писать на support (собачка) blind (точка) games.

(Страница 1 из 4)

Blind games - Звуковые игры незрячим → Создание игр, программирование → BGT. Делимся опытом: кодинг, решения задач в программировании.

Страницы 1 2 3 4 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Topic RSS feed

Сообщений с 1 по 10 из 40

1 (Thu-01-16 21:18:15 отредактировано McDanilRus)

Тема: BGT. Делимся опытом: кодинг, решения задач в программировании.

Здесь прошу делиться своими наработками, решениями тех или иных задач в программировании на BGT.
Просьба не флудить, критика приветствуется с демонстрацией правильного решения.
Надеюсь получатся какбы статьи, которые помогут каждому в творении игр.

Хорошо(+) Плохо(-)

2

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Предлагаю своё решение вывода речевых сообщений в проекте.
Я считаю, что в игре должно поддерживаться 2 скринридера, это jaws и nvda, остальное мало интересно, по крайней мере для меня, хотя в любое время можно добавить и остальные.
Для меня важно чтобы сообщения произносились перебивая предыдущие, чтобы как можно быстрее была проговорена новая информация., хотя и тут можно было бы создать функцию, которая исходя из входного параметра, перебивала речь или нет.
Я использую отдельный скрипт (модуль), чтобы можно было легко прикручивать его к другому проекту, что и предлагаю вам.

Создаём главный файл BGT, например, main.bgt.
Также создаём файл speak_message.bgt, это и будет отдельным модулем.

Кодим в speak_message.bgt.

// функция для загрузки библиотеки dll для nvda
void nvda_library_load() {
// загружаем библиотеку, при этом сама она должна лежать в папке с игрой, а именно файл nvdaControllerClient32.dll
screen_reader_set_library_path(NVDA, "nvdaControllerClient32.dll");
}

// функция выгружает библиотеку nvda, нужно, когда игра закрывается, освобождая оперативную память
void nvda_library_unload() {
screen_reader_unload_library(NVDA);
}

// функция для озвучивания сообщения, принимает строковый параметр
void say_message(string mess) {
// объявляем переменную (флаг), для поиска загруженных скринридеров, инициализируем как ложь (не найдено)
bool found_reader=false;
// ищем загруженный jaws, если находим, то флаг поиска скринридера изменяем на true, и передаём сообщение в jaws для произношения
if(screen_reader_is_running(JAWS)) {
found_reader=true;
screen_reader_speak_interrupt(JAWS, mess);
}
// также поступаем с nvda
if(screen_reader_is_running(NVDA)) {
found_reader=true;
screen_reader_speak_interrupt(NVDA, mess);
}
// проверяем истинность флага поиска скринридеров, и если ложь, скринридеры не найдены, то выводим об этом сообщение ввиде алерта
if(!found_reader) {
alert("Внимание!", "Не найдено ни одного скринридера, попробуйте перезагрузить говорящую программу и игру.");
}
}

// функция для затыкания скринридеров
void stop_speech() {
// если jaws работает то заткнуть, чтобы прервать сообщение
if(screen_reader_is_running(JAWS)) {
screen_reader_stop_speech(JAWS);
}
// также с nvda
if(screen_reader_is_running(NVDA)) {
screen_reader_stop_speech(NVDA);
}
}

Конец кодинга.

Всего 4 функции мне показалось достаточным, чтобы конфортно выводить речевые сообщения.
Теперь используем наш модуль в главном скрипте.

Кодим main.bgt.

// подключаем скрипт speak_message
#include "speak_message.bgt";

// главная функция или точка входа в программу
void main() {
// перехватываем клавиши на себя, чтобы скринридеры не могли их блокировать
install_keyhook();
// вызываем функцию для загрузки библиотеки nvda
nvda_library_load();
// показываем окно игры
show_game_window("Игра");

// здесь можно вызывать меню и творить другие вещи, которые необходимы до старта игры

// вызываем функцию game(), которая будет ниже, она собственна и отвечает за процесс игры
game();
// после отработки функции, а она будет зациклена, то есть закончит работу когда будет нужно закрыть игру, мы освобождаем память, а именно выгружаем библиотеку nvda
nvda_library_unload();
// убераем перехват клавиатуры
uninstall_keyhook();
// здесь игра закончиться и закроется, так как это конец главной функции main()
}

// функция игры
void game() {
// создаём бесконечный цикл
while (true) {
// если нажата стрелка вверх
if (key_pressed(KEY_UP)) {
// передаём сообщение на озвучку
say_message("Нажата стрелка вверх");
}
// если нажата клавиша энтер
if (key_pressed(KEY_RETURN)) {
// тоже отправляем на озвучку сообщение
say_message("Нажата клавиша энтер");
}
// если нажата клавиша левый контрол
if (key_pressed(KEY_LCONTROL)) {
// вызов функции для затыкания скринридера
stop_speech();
}
// аналогично с правым контролом
if (key_pressed(KEY_RCONTROL)) {
stop_speech();
}
// если нажата клавиша эскейп
if (key_pressed(KEY_ESCAPE)) {
// на всякий случай прощаемся речевым сообщением
say_message("до свидания");
// чуток ждём
wait(1500);
// прерываем наш вечный цикл и игра выгружается
break;
}
// ждём в каждой итерации цикла 5 милисекунд
wait(5);
}
}

Конец кодинга.

Таким образом, мы получили отдельный скрипт для озвучивания сообщений, и можем легко прикручивать к новым проектам.
Нам не надо больше думать как же там мы раньше проверяли включен ли jaws или nvda, как им передавать сообщения.
У нас 4 функции, которые можно глянуть в коде скрипта, чтобы вспомнить их имена, и оперировать ими в своей игре, при этом четвёртой можно не пользоваться если не нужно затыкания скринридеров.
При использовании данного скрипта, у нас будут сообщения произносится включенным скринридером, либо jaws, либо nvda, если включены оба, то говорить будут оба, если выключены оба, то выйдет информационное окно об этом.
Не забывайте ложить библиотеку nvda в папку с игрой, иначе игра её не найдёт и выдаст ошибку, взять библиотеку nvdaControllerClient32.dll можно в папке движка BGT, а там по пути redist\screen_readers\nvda.
На этом всё, всем творчества!

Хорошо(+) Плохо(-)

3 (Fri-01-16 17:16:42 отредактировано Igorek)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Разберался с меню в игре, вот задачи которые хотелось решить:
1. необходимость в быстром подключении меню к любому проекту.
(решено частично, устраивает).
2. меню должно создаваться из файла, или string переменной, например, переданной по интернет.
(string это строка, но она может в себе содержать знак "новая строка", а это значит что по сути в ней несколько строк, правильнее их называть части строк разделённые знаком "новая строка".
натафтологил уже, но подругому не сказать :D, дальше будет яснее)
3. меню должно быть гибким.
(например, если в подменю жмём "эскейп", то возвращаемся в предыдущее, при этом на тот пункт куда заходили)

у нас будет модуль "menu.bgt", файл "start_menu.dat" в папке data, и код в главном скрипте игры.
ещё нужен звуковой файл "menumove.wav" в папке "sounds".
разбираемся с файлом "start_menu.dat". назвал я его так потому что делаем главное меню игры, для другого меню можно создавать другие файлы и сколько угодно. его содержимое в нашем примере такое:

menu=Начать игру,Создать героя,Настройки,Выход|Добропожаловать на земли ависа
menu=Сервер1,Сервер2,Сервер3,Сервер4,В предыдущее меню|Выберите сервер
menu=Настройка1,Настройка2,Назад|Настройки

все строчки начинаются с "menu=", должно понадобиться при получении меню через интернет, чтобы отличить строку меню от других строковых данных.
дальше перечисление пунктов меню через запятую.
и в конце описание меню, отделено вертикальной чертой
первая строка используется как начальное меню, вторая - как подменю первого пункта, а третья - как подменю третьего пункта. для остальных пунктов, а именно для 2 и 4 нам подменю пока не нужны.

кодим menu.bgt, коментарии будут не очень подробдные, знающий разберётся.

#include "dynamic_menu.bgt"; // подключили модуль меню

dynamic_menu menu; // объект класса dynamic_menu
sound menu_movement; // объект sound, звук движения по меню
int menu_position; // позиция в меню

// функция создания меню
int create_menu(string file_menu, string str_menu, int n_str, bool allow_escape, bool wrap, bool enable_home_and_end, int start_position) {
menu.reset(true); // обнуляем полностью меню
menu.allow_escape=allow_escape; // указали реакцию на клавишу "эскейп"
menu.wrap=wrap; // указали необходимость цикличного перемещения
menu.enable_home_and_end = enable_home_and_end; // указали реакцию клавиш "home" и "end"
menu.set_speech_mode(what_screen_reader()); // указали какой скринридер используется из функции what_screen_reader(), которая ниже
menu_movement.load("sounds/menumove.wav"); // подгрузили звуковой файл
menu.set_callback(check_menu_events, ""); // указали функцию обратного вызова, которая тоже будет ниже
if (str_menu =="") { // условие если строка пришла пустая то работаем с файлом
file f; // объявили файловую переменную
f.open(file_menu, "r"); // открыли файл для чтения
str_menu = f.read(); // заполнили нашу пустую переменную содержимым из файла
f.close(); // закрыли файл
}
string[] array_str_menu = string_split(str_menu, "\n", true); // создали массив строк из строки str_menu на основе разделения по знаку "новая строка". например из нашего файла будет создан массив из трёх строк (см. содержимое файла выше)
string Description_menu = string_split(array_str_menu[n_str -1], "|", true)[1]; // вытащили из нужной строки описание меню
string[] array_items = string_split(string_split(string_split(array_str_menu[n_str -1], "|", true)[0], "=", true)[1], ",", true); // создали массив и внесли в него пункты меню из нужной строки
// перебираем этот массив и заполняем меню
for (int counter = 0; counter < array_items.length; counter++) {
menu.add_item_tts(array_items[counter]);
}
int result_menu = menu.run_extended(Description_menu, true, start_position, true); // запустили меню, указав при этом какой пункт меню будет установлен, в result_menu возвращается пункт меню на который было нажато, здесь начинает отрабатывать функция обратного вызова
menu_movement.close(); // меню отработало, закрываем звуковой файл
return result_menu; // вернули пункт меню на который было нажато
// здесь отработка модуля завершена, но ниже две функции которые вызываются из текущей функции
}

// функция обратного вызова, циклично вызывается пока меню запущено, то есть пока не нажато на любой пункт меню
int check_menu_events(dynamic_menu@ game_menu, string data) {
if(game_menu.get_position()!=menu_position) { // условие. если текущая позиция отличается от сохранённой
menu.set_speech_mode(what_screen_reader()); // снова берём значение запущенного скринридера
menu_movement.stop(); // останавливаем воспроизведение звука
menu_movement.play(); // воспроизводим звук движения по меню
menu_position=game_menu.get_position(); // сохраняем позицию меню
}
return 0; // возвращаем 0, иначе меню закроется, то есть в функции обратного вызова можно прерывать меню, может быть где-то полезным, но нам пока не нужно
}

// функция проверки запущенного скринридера, сделал её здесь, чтобы модуль меню был как можно более независимый
int what_screen_reader() {
// если запущен джоз то его и возвращаем
if(screen_reader_is_running(JAWS)) {
return JAWS;
}
// также с nvda
if(screen_reader_is_running(NVDA)) {
return NVDA;
}
return JAWS; // если условия не выполнились то все равно возвращаем джоз, можно было бы и SAPI вернуть но я не хочу с этим связываться
}

конец кодинга

теперь опишу входные параметры функции
int create_menu(string file_menu, string str_menu, int n_str, bool allow_escape, bool wrap, bool enable_home_and_end, int start_position)
string file_menu - путь до файла меню, в нашем случае это sounds/start_menu.dat
string str_menu - строка меню, если она пустая то берётся из файйла. если передаём её заполненную, то file_menu можно передавать пустым
int n_str - номер элемента массива, который заполняется строчками, когда мы делили основную строку на другие по знаку "новая строка"
bool allow_escape - если труе то то клавишей "эскейп" меню возвращает 0, иначе не реагирует на неё
bool wrap - если true, то меню будет прокручиваться циклично
bool enable_home_and_end - если true, то клавишами "home" и "end" будет происходить переход в начало или в конец меню
int start_position - номер того меню, на которое попадает курсор при открытии меню, этот параметр очень важен, и далее мы увидим как здорово получается манипулировать менюшкой

теперь в главном скрипте мы во входной функции вызываем наше меню, хотя это не обязательно можно делать здесь, можно меню вызывать в других местах, с другими данными, имею ввиду либо из файла либо из строки.
значит в main() пишем
void main() {
show_start_menu(1);
}
тем самым вызвали функцию передав значение 1.
а теперь самое интересное, я тремя похожими функциями обрабатываю движения по меню, первую из них только что вызывали из main()
кодим их

// первая функция открывает начальное меню
void show_start_menu(int pos) { // принимаемое значение, это номер пункта, который станет активным
int r = create_menu("data/start_menu.dat", "", 1, true, false, true, pos); // вызываем функцию создания меню с нужными параметрами и результат записываем в r
// обратите внимание на параметр 1, это означает первая строка в файле, откуда берётся начальное меню
// ниже условие switch, обрабатываем r
switch(r){
case -1: exit(); break; // если -1 то ошибка, закрываемся
case 0: exit(); break; // если 0 то нажата была клавиша "эскейп", ошибки нет, пользователь закрыл сам, ну тоже закрываемся
case 1: show_start_menu1(1); break; // если 1, то есть нажато на первый пункт в меню, то создаём следующее меню, со стартовой позицией 1
case 2: game(); break; // если 2 то пока запускаем функцию game(), надо конечно обрабатывать но у нас тема другая
case 3: show_start_menu3(1); break; // если 3, то есть нажато на третий пункт в меню, то создаём следующее меню, со стартовой позицией 1
case 4: exit(); break; // если нажато на пункт 4, а это выход, то закрываемся
}
}

void show_start_menu1(int pos) {
int r = create_menu("data/start_menu.dat", "", 2, true, false, true, pos); // аналогично с функцией выше, создали меню, но берём уже вторую строчку из файла
switch(r){
case -1: exit(); break;
case 0: show_start_menu(2); break; // запускаем предыдущую функцию, то есть создаём снова главное меню и активный пукнт уже второй. то есть если пользователь нажмёт "эскейg" то попадает в главное меню но остаётся на пункте откуда вышел
case 1: game(); break; // вызываем game(), вобщем не обрабатываем пока
case 2: game(); break; // аналогично
case 3: game(); break; // тоже самое
case 4: game(); break; // и опять
case 5: show_start_menu(1); break; // а тут аналогично с эскейпом, только активным будет пункт 1
}
}

// функция создаёт подменю третьего пункта главного меню
void show_start_menu3(int pos) {
int r = create_menu("data/start_menu.dat", "", 3, true, false, true, pos); // также как и раньше, только берём третью строку из файла
switch(r){
case -1: exit(); break;
case 0: show_start_menu(3); break; // если нажата "эскейп", то возвращаемся в главное меню, на пункт 3
case 1: show_start_menu3(1); break; // здесь можно обработать результат и мы запускаем снова эту же функцию с активным пунктом 1
case 2: show_start_menu3(2); break; // и здесь мы запускаем саму себя, но активным пункт уже будет 2
// поясню выше сказанное, мы сделали такое меню, где нажатие на пункт как бы ничего не делает, вернее возвращает результат и снова запускает себя, нужно это для настроек, если мы в меню настройки на пункте нажимаем энтер, то можем переключить что-то, и при этом останемся тамже и можем переключать энтером сколько душе угодно
case 3: show_start_menu(1); break; // если нажат пункт "назад" то открываем главное меню.
}
}

Конец кодинга.
Уф. вобщем если не понятно или есть другие решения то пишем не стесняемся.
итог таков:
я беру модуль menu.bgt, не забываем его подключить кстати,
редактирую файл меню, как мне надо,
обрабатываю результаты в скрипте игры, запуская по несколько раз эти менюшки и подменюшки.
можно создавать меню глубже, но все надо будет обрабатывать.
обратите внимание:
если у нас строка в файле
menu=Старт,Об игре, Выход|Добропожаловать в игру
то результат который вернётся может быть от -1 до 3,
где -1 значит произошла ошибка
0 нажата клавиша эскейп
остальное номер пунктов меню.
На этом всё, всем творческих идей

Хорошо(+) Плохо(-)

4

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Привет, Igorek. Большое спасибо за интересный модуль речевого вывода сообщений средствами джоз и НВДА. Но возник такой вопрос, если возможно, не мог бы ты показать пример использования данного модуля при создании меню и озвучке его пунктов? А то вся игра озвучивается диктором, а вот одна менюшка желательно, чтобы либо джозом, либо НВДА озвучивалась. Пункты меню заранее будут неизвестны. в качестве текста пункта будет передаваться аргумент типа address[1] сама менюшка работает, но озвучивается сапи, и конечно же если будут кирилические пункты меню, то они не озвучатся. поэтому данный модуль стал бы хорошим подспорьем. Ниже так же видел модуль для создания меню, обязательно возьму его и потестирую, но на данный момент меню у меня создано совсем подругому. Кстати, а ты давно занимаешься программированием игр? Большое спасибо. С уважением, Буяльский Владислав.

5

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

dynamic_menu m;
int result;
m.allow_escape=true;
m.wrap=true;
m.set_speech_mode(NVDA);
m.add_item_tts("Первый пункт меню");
m.add_item_tts("Второй пункт меню");
m.add_item_tts("И так далее");
result=m.run("Выбирите пункт меню", true);

6 (Fri-03-16 18:40:03 отредактировано Igorek)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

vlad-mus пишет:

Привет, Igorek. Большое спасибо за интересный модуль речевого вывода сообщений средствами джоз и НВДА.

не за что smile я его подправил чуток, напишу в след сообщение

vlad-mus пишет:

Но возник такой вопрос, если возможно, не мог бы ты показать пример использования данного модуля при создании меню и озвучке его пунктов? А то вся игра озвучивается диктором, а вот одна менюшка желательно, чтобы либо джозом, либо НВДА озвучивалась. Пункты меню заранее будут неизвестны. в качестве текста пункта будет передаваться аргумент типа address[1] сама менюшка работает, но озвучивается сапи, и конечно же если будут кирилические пункты меню, то они не озвучатся. поэтому данный модуль стал бы хорошим подспорьем.

распишу в след сообщении как я решил реализовать менюшку, постараюсь подробно рассказать, так как этот вариант меня уже не устраивает из-за минусов. и напишу как модуль вывода текста в речь использую

vlad-mus пишет:

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

может у вас реализовано правильнее, сравните с моим вариантом, напишу о нем в след сообщении.

vlad-mus пишет:

Кстати, а ты давно занимаешься программированием игр?

достаточно давно, не только игр, а вообще програмированием, наткнулся случайно на BGT, очень заинтересовало. только хочется серъезный проект написать, а это не просто, вот будет посвободнее время, наверно что=-то напишу. язык прост и достаточно функционален. жаль только с базами данных нет возможности работать, надо думать с созданием dll библиотеки, или искать другое решение, что меня и затормозило, так как в моих планах создать игру, где будут не просто вещи какие то для героя, но и абгрейд этих вещей, а без баз данных это тяжело реализовать. да и база считывается и записывается быстрее чем просто файлы какие то типа текста.

а минуса объектов dynamic_menu в том, что не возможно поставить звуки на границы менюшкек, ну типа вниз дошли, и ещё раз вниз воспроизводиться звук, означающий что ниже нельзя уже.
может я не нашел как сделать. вернее сделать то можно но надо копаться в самом модуле dynamic_menu.bgt
да и не нашел как переххватывать события движения по меню, то есть не только звуки границ а и вообще звуки движения по меню не понял как реализовать.
также нельзя обрабатывать нажатия других клавиш, что очень важно на мой взгляд. например, вот в меню настройка, зашли, там пункты меню, нажатие энтер на которые меняют значения, и тут вот в dinamic_menu я не решил как лучше всего перехватывать событие, чтобы исполнить код изменения настройки.

Хорошо(+) Плохо(-)

7 (Fri-03-16 20:38:11 отредактировано Igorek)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Вот такой конечный вариант модуля вывода текстовых сообщений через скринридеры или sapi, или через Алерт сообщение

модуль voice.bgt
естественно подключаем его в главном файле проекта
#include "voice.bgt";
наверно не правильно я его назвал ну тут поправить не проблема
сам модуль

tts_voice speech;

//загружаем нужные библиотеки
void screen_reader_librarys_load() {
screen_reader_set_library_path(NVDA, "nvdaControllerClient32.dll");
screen_reader_set_library_path(SYSTEM_ACCESS, "SAAPI32.dll");
}

//выгружаем нужные библиотеки
void screen_reader_librarys_unload() {
screen_reader_unload_library(NVDA);
screen_reader_unload_library(SYSTEM_ACCESS);
}

//Функция затыкания предыдущего сообщения
void stop_speech() {
int reader = what_screen_reader(); // взяли работающий скринридер чтобы его заткнуть
if (reader > 0) {
screen_reader_stop_speech(reader);
} else {
speech.stop();
}
}

//берём работающий скринридер, необходимо много где, например чуть выше когда брали для затыкания
int what_screen_reader() {
if(screen_reader_is_running(JAWS)) {
return JAWS;
}
if(screen_reader_is_running(NVDA)) {
return NVDA;
}
if(screen_reader_is_running(WINDOW_EYES)) {
return WINDOW_EYES;
}
if(screen_reader_is_running(SYSTEM_ACCESS)) {
return SYSTEM_ACCESS;
}
return 0;
}

//функция собственно для вывода текста
//3 параметра важен только первый, собственно строка, второй булевый, если true, то сообщение принудительное, затыкает предыдущее, если false, то ждет пока договорит скринридер предыдущее сообщение, третий параметр, если true, то говорит скринридерами, иначе покажет алерт
void show_info(string info, bool say_interrupt = true, bool say_info = true) {
if (!say_info) {
alert(str_message+":",info+"\r\n"+str_press_ok);
return;
}
//вот если false, то собственно показываем сообщение в алерте, и прервали функцию
//ниже берем опять активный скринридер и заставляем его произнести сообщение
int reader = what_screen_reader();
if (reader>0){
if (say_interrupt) {
screen_reader_speak_interrupt(reader, info);
} else {
screen_reader_speak(reader, info);
}
} else {
if (say_interrupt) {
speech.speak_interrupt(info);
} else {
speech.speak(info);
}
}
}

конец модуля.

дальше показываю как использую.
будет немножко сложный код может быть.
сначала модуль меню, но он не универсален, поэтому для каждого проекта надо будет переделывать.
назвал я его menu.bgt
не забудем подключить к проекту
в модуле используются константы вместо строк и номеров, их я приводить не буду, они в отдельном модуле
сам модуль

string[] items; //массив со строками пунктов меню
int pos_menu; //номер позиции курсора в меню

//функция заполняет стартовое меню
// параметром передается позиция курсора
void show_start_menu(int position) {
items.resize(4);
items[0] = str_enter_menu;
items[1] = str_account_menu;
items[2] = str_settings_menu;
items[3] = str_exit_menu;
pos_menu = position;
show_info(str_start_menu);
show_info(items[pos_menu -1],false);
// вот две строки передача строк на озвучку или показ в алерте
// в последней передал false, это чтобы не перебило предыдущее сообщение
}

//функция показывает меню когда нажали на первый пункт "войти", но может менюшки не быть, уже стартовать игра должна, и обработка тут не нужна
void show_enter_menu() {
//кода пока нет
}

// анлогичная функция, показывает меню управления акаунтом, там пункты типа зарегистрироваться и т.п.
void show_account_menu(int position) {
items.resize(4);
items[0] = str_account_enter_menu;
items[1] = str_account_registration_menu;
items[2] = str_account_delete_menu;
items[3] = str_back_menu;
pos_menu = position;
show_info(str_account_caption_menu, false);
show_info(items[pos_menu -1],false);
}

// меню настроек аналогична тоже
void show_settings_menu(int position) {
items.resize(3);
items[0] = str_setting1_menu;
items[1] = str_setting2_menu;
items[2] = str_back_menu;
pos_menu = position;
show_info(str_settings_caption_menu);
show_info(items[pos_menu -1],false);
}

// а тут тоже менюшка которая показывается при выходе из игры, типа да или нет вопрос
void show_exit_menu(int position) {
items.resize(2);
items[0] = str_yes;
items[1] = str_no;
pos_menu = position;
show_info(str_exit_caption_menu);
show_info(items[pos_menu -1],false);
}

// обработка стрелки вверх
void menu_go_up() {
if (pos_menu > 1) {
pos_menu = pos_menu -1;
show_info(items[pos_menu -1]);
} else {
show_info(items[pos_menu -1]);
}
}

// обработка стрелки вниз
void menu_go_down() {
if (pos_menu < items.length) {
pos_menu = pos_menu +1;
show_info(items[pos_menu -1]);
} else {
show_info(items[pos_menu -1]);
}
}
конец модуля

а теперь самое сложное и интересное
главный модуль, там правда ещё интернет подключение но не обращаем внимание
модуль назван main.bgt
собственно код
#include "form.bgt";
#include "voice.bgt";
#include "menu.bgt";
#include "constants.bgt";
#include "strings.bgt";
#include "network.bgt";
#include "account.bgt";
// подключил все модули

int[] status(2); // массив статусов игры
bool waiting;

void main() {
install_keyhook();
screen_reader_librarys_load(); // загружаем библиотеки из модуля voice.bgt, чтобы все скринридеры были готовы к озвучке. почему именно тут, потому что только главный модуль игры знает где загружать и выгружать их
show_game_window("Земли Ависа");
wait(1000);
status[0] = cm_menu;
status[1] = cs_start_menu;
waiting = true;
while (true) {
if (waiting) {
waiting = false;
switch (status[0]) {
case cm_menu:
if (status[1]==cs_start_menu) show_start_menu(1);
if (status[1]==cs_enter_menu) show_enter_menu();
if (status[1]==cs_account_menu) show_account_menu(1);
if (status[1]==cs_settings_menu) show_settings_menu(1);
if (status[1]==cs_exit_menu) show_exit_menu(1);

if (status[1]==cs_account_enter_menu){show_account_menu(1); status[1]=cs_account_menu;}
if (status[1]==cs_account_registration_menu){registration_hero(); show_account_menu(2); status[1]=cs_account_menu;}
if (status[1]==cs_account_delete_menu){show_account_menu(3); status[1]=cs_account_menu;}
if (status[1]==cs_account_back_menu){show_start_menu(2); status[1]=cs_start_menu;}
if (status[1]==cs_setting1_menu){show_settings_menu(1); status[1]=cs_settings_menu;}
if (status[1]==cs_setting2_menu){show_settings_menu(2); status[1]=cs_settings_menu;}
if (status[1]==cs_settings_back_menu){show_start_menu(3); status[1]=cs_start_menu;}
if (status[1]==cs_exiting_yes) exit_program();
if (status[1]==cs_exiting_no){ status[1] =cs_start_menu; show_start_menu(1);}
break;

}

} // end if (waiting)
keyboard_commands();
wait(5);
}
}
// вобщем единственный что считаю правильным, цикл в игре, где идет обработка игры.
// первое если нужно то показываем необходимое меню, второе вызывается функция для обработки нажатий клавиш, которая ниже.

void keyboard_commands() {
if (status[0]==cm_menu) {
if (key_pressed(KEY_RETURN)) {
if(status[1]==cs_start_menu) { status[1]=pos_menu; waiting = true; return; }
if(status[1]==cs_account_menu) { status[1]=cs_account_menu*100+pos_menu; waiting = true; return; }
if(status[1]==cs_settings_menu) { status[1]=cs_settings_menu*100+pos_menu; waiting = true; return; }
if(status[1]==cs_exit_menu) { status[1]=cs_exit_menu*100+pos_menu; waiting = true; return; }
} // end KEY_RETURN
if (key_pressed(KEY_ESCAPE)) {
if(status[1]==cs_start_menu) { status[1]=cs_exit_menu; waiting = true; return; }
if(status[1]==cs_account_menu) { status[1]=cs_account_back_menu; waiting = true; return; }
if(status[1]==cs_settings_menu) { status[1]=cs_settings_back_menu; waiting = true; return; }
if(status[1]==cs_exit_menu) { status[1]=cs_start_menu; waiting = true; return; }
} // end KEY_ESCAPE
if (key_pressed(KEY_UP)) {
menu_go_up();
} // end KEY_UP
if (key_pressed(KEY_DOWN)) {
menu_go_down();
} // end KEY_DOWN
} // end cm_menu
if (key_pressed(KEY_F12)) {
show_info("Пинг "+host.get_peer_average_round_trip_time(server_id));
}
if (key_pressed(KEY_LCONTROL)||key_pressed(KEY_RCONTROL)) {
stop_speech();
}
}
// ну тут обработка клавиш, заметим что контролы затыкают речь, а при нажатии эскейп срабатывают условия либо выход в предыдущее меню либо вопрос на выход из игры. энтер обрабатывает нажатия на пункты меню например видно что при нажатии на настройку можно добавить код, чтобы изменить эту самую настройку воспроизвести звук и вообще что угодно
// вобщем код сложен используются константы но не буду в подробности вдаваться, главное затыкание речи контролами

void exit_program() {
screen_reader_librarys_unload(); именно при выходе выгружаем библиотеки что важно заметить. не просто exit
uninstall_keyhook();
exit();
}

конец кода
понятно что сыро и константы я не все перевел в отдельный модуль, да и с константами немножко код сложноват для понимания
вот ссыль на проект
https://yadi.sk/d/UliA0BnOq5vX9
только не стоит нажимать на войти в проекте, придется тогда выбивать из процессов, а так по меню ходит возвращается, всё норм озвучивается.
а вообще конечно все это не описать.

Хорошо(+) Плохо(-)

8

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Народ, тут на форуме мноооого было звона по поводу создания онлайн игр на bgt. так вот, ловите мой пример сервака и клиента. описание:
клиент может подключаться к серверу, введя ip, port и своё имя.
когда подключение произойдёт, клиент может нажимать энтер, и все остальные клиенты получат извещение о том, что он это сделал. если у вас и после этого примера возникнут проблемы с network, то я уж и не знаю, как ещё расжевать, чтобы дошло. https://yadi.sk/d/HUZG--qRq94Az

9

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Вот ещё один пример от меня, в котором я показываю, как создавать fps. Чтобы повороты были. На поле всегда лежит 1 объект, который вы можете брать, подойдя к нему вплотную. на c можно посмотреть свои координаты, на z можно глянуть свой поворот в градусах, на энтер можно узнать, сколько набрано очков. И вот мой вам, ребята, совет:
пытайтесь делать что-либо сами.
И не надо говорить, что мол времени нету и т. д.
Если уж собрался что-то писать, то пиши, а не хватай урывками тут и там.
Тогда, думаю, у вас получится гораздо больше.
https://yadi.sk/d/fWRYPunPq9Ljn

10

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

большое спасибо за пример fps! очень помог разобраться с rotation package. может даже пока есть время что-нибудь простенькое напишу. вот только не понимаю я как рассчитать выстрел в игре. как узнать расстояние это понятно, есть функция, а как рассчитать что игрок смотрит на врага? и как сделать погрешность в 1 2 градуса чтобы было легче играть.

Хорошо(+) Плохо(-)

Сообщений с 1 по 10 из 40

Страницы 1 2 3 4 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Blind games - Звуковые игры незрячим → Создание игр, программирование → BGT. Делимся опытом: кодинг, решения задач в программировании.



Currently installed 4 official extensions. Copyright © 2003–2009 PunBB.

Сгенерировано за 0.087 секунды (92% PHP — 8% БД) 10 запросов к базе данных