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

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

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

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

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

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

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

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

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

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

Topic RSS feed

Сообщений с 11 по 20 из 40

11

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

Кирилл, допустим, что игрок - это vector p(1, 1, 0);, тогда его враг будет vector enemy(10, 10, 0);. Значит, чтобы рассчитать отношение градусной меры до него, надо написать такое условие в цикле игры:
if(calculate_x_y_angle(p.x, p.y, enemy.x, enemy.y, turn)>345 and calculate_x_y_angle(p.x, p.y, enemy.x, enemy.y, turn)<=15 and radar.elapsed>500) {
s.play_stationary("radar.wav", false);
radar.restart();
}
Понимаешь, когда ты прямо смотришь на какой-либо объект, calculate_x_y_angle будет равно нулю.
Вот я и сделал такое условие, что, если calculate_x_y_angle больше 345 и меньше равно 15, то проигрывается звук радара, мол типо пушку нацелили, можно стрелять.
Вот как-то так.

12

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

asffix пишет:

Кирилл, допустим, что игрок - это vector p(1, 1, 0);, тогда его враг будет vector enemy(10, 10, 0);. Значит, чтобы рассчитать отношение градусной меры до него, надо написать такое условие в цикле игры:
if(calculate_x_y_angle(p.x, p.y, enemy.x, enemy.y, turn)>345 and calculate_x_y_angle(p.x, p.y, enemy.x, enemy.y, turn)<=15 and radar.elapsed>500) {
s.play_stationary("radar.wav", false);
radar.restart();
}
Понимаешь, когда ты прямо смотришь на какой-либо объект, calculate_x_y_angle будет равно нулю.
Вот я и сделал такое условие, что, если calculate_x_y_angle больше 345 и меньше равно 15, то проигрывается звук радара, мол типо пушку нацелили, можно стрелять.
Вот как-то так.

спасибо огромное за объяснение! и ещё вопрос: а как можно обрабатывать карту со стенами? допустим есть арена 20 на 20 клеток. и по квадрату стены. как не выпустить игрока за стены? или ещё как добавить одиночную стенку типа столба в середине?

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

13

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

и вообще как можно создать и обработать карту со стенами и звуками? уже давно вроде где-то было такое, но там код был без комментов, и очень кривой. да и я тогда ещё мало что знал. так что если не очень сложно, можно пример простейшей бродилки но с картой. желательно 3д бродилку.

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

14

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

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

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

15

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

Кирилл, я же писал статью по созданию карт. http://www.blinde-games.ru/495-bgt-sozd … -igre.html

16

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

Так, народ, здесь чисто выкладываем свои творения и комментируем их. все вопросы задавайте сюда: http://www.blinde-games.ru/forum/viewtopic.php?id=5 . не надо флудить не по теме. все сообщения с вопросами не по теме буду удалять лично. пишем в тему, ссылка выше.

17 (Fri-07-16 00:23:16 отредактировано Igorek)

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

Здравствуйте!
Тишина у нас, наверно все что-то пишут пишут, и я тут немного програмировал, хочу поделиться тем, что у меня есть.
Вообще, я решаю задачу с картами, вернее она решена что касаемо местности, но на карте могут быть ещё объекты. я их тоже уже научился добавлять использовать, ищу решение более верное, и как можно менее ресурсоёмкое.
Я хочу рассказать о программе картограф, это та программа, в которой мы рисуем карту, ну и о том, как эту карту использовать.
но для начала приведу код отдельного модуля, который отвечает за вывод информации, вы можете его сохранить, и подключать к своему проекту.
этот модуль я выше давал, но сейчас я его более автоматизировал
лично я модуль назвал info_manager.bgt.

//начало кода
Info_manager info_manager; // объявили объект класса Info_manager, сам класс ниже

// функция для вывода инфы, можно выводить черезз речь, или диалоговым информационным окном
void show_info(string info, bool say_interrupt = true, bool say_info = true) {
info_manager.show_info(info, say_interrupt, say_info); // вызвали метод вывода информации в нашем объекте
}

// функция прерывания речи
void stop_speech() {
info_manager.stop_speech(); // аналогично вызвали соответствующий метод в нашем объекте
}

// функция возвращает запущенный скринридер, нужна например при созздании формы, ведь audio_form принимает в себя скринридер для озвучки, но о ней пока рано говорить, у нас другая тема
int what_screen_reader() {
return info_manager.what_screen_reader();
}

// функция мониторинга, она нужна для того чтобы освобождать клавиши клавиатуры если окно свёрнуто, но подробнее в соответствующем методе
void monitor_info_manager() {
info_manager.monitor();
}

// строковая константа, используется для заголовка окна, когда инфа выводиться в окне
const string str_message="Сообщение";
// конечно её лучше переместить в соответствующий строковым константам модуль, если вы это делаете

// сам класс
class Info_manager {
tts_voice speech; // объект для вывода речи
bool active_window; // переключатель, нужен для проверок окна, свернулось оно или развернулось

// конструктор
Info_manager() {
screen_reader_librarys_load(); // функция которая сама находиться ниже, подгружает библиотеки dll
active_window = true; // переключатель в true, так как окно у нас развернуто изначально
install_keyhook(); // включили перехват клавиш
}

// вот функция загрузки dll
void screen_reader_librarys_load() {
screen_reader_set_library_path(NVDA, "nvdaControllerClient32.dll");
screen_reader_set_library_path(SYSTEM_ACCESS, "SAAPI32.dll");
}

// функция выгрузки 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;
}

// главная функция, выводит информацию
// подробнее после кода, как пользовать какие параметры и прочее
void show_info(string info, bool say_interrupt = true, bool say_info = true) {
if (!say_info) {
alert(str_message+":",info);
return;
}
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);
}
}
}

// мониторинг, то есть её надо вызывать в цикле, а здесь проверка, если окно свернуто или развёрнуто
// вообще можно её не вызывать, подробнее после кода
void monitor() {
if (is_game_window_active()) {
if (!active_window) {
active_window = true;
install_keyhook();
}
} else {
if (active_window) {
active_window = false;
uninstall_keyhook();
}
}
}

// диструктор
~Info_manager() {
uninstall_keyhook();
screen_reader_librarys_unload();
}

}

// конец кода

итак, кто понял и внимательно прочитал код, уже должны понять, что модуль надо подключить, а инициализацию работы он выполнит сам. напишу всё же как мы его используем.
подключаем такой строкой
#include "includes/info_manager.bgt";
обратите внимание, что у меня модуль лежит в папке includes, поэтому и путь я указал такой
всё! больше ничего делать не надо, теперь только при выводе ифнормации мы пишем вызов функции и указываем параметры, например так:
show_info("Привет, МИР!");
но в функции есть параметры, ими можно манипулировать, вот описание этой функции
void show_info(string info, bool say_interrupt, bool say_info)
info - строка, та инфа, которую нужно вывести
say_interrupt - не обязательный параметр, поумолчанию true, указывает нужно ли прервать предыдущую речь синтезатора
say_info - не обязательный параметр, поумолчанию true, указывает, нужно ли произнести, если false то информация будет показана в окне

примеры:
show_info("Привет, МИР!", false); // произнесет строку, но дождется пока скринридеры договорят, то есть речь не будут прерывать.
show_info("Привет, МИР!", false, false); // покажет строку в окне, причем тут без разницы какое второе значение, то есть show_info("Привет, МИР!", true, false); это практически тоже самое
show_info("Привет, МИР!", true, true); // это тоже самое что show_info("Привет, МИР!"); и предпочтительнее не писать лишние параметры, ведь они изначально у нас оба true. будет произнесена речь с прерыванием, что обычно и необходимо в играх

ещё есть монитор, его можно не пользовать, но если хотите чтобы при сварачивании окна клавиши не  перехватывались игрой, то пользуйте, ххотя честно разницы почти нет

ниже пример, мы в нем по нажатию на энтер говорим текст, по нажатию на пробел показываем текст в окне, эскейп закроет программу, ну и в цикле мониторим

// начало кода
#include "includes/info_manager.bgt";

void main() {
show_game_window("тест");
while(true) {
if(key_pressed(KEY_RETURN)) {
show_info("Работает");
}
if(key_pressed(KEY_SPACE)) {
show_info("Это должно быть показано в окне",false,false);
}
if(key_pressed(KEY_ESCAPE)) {
exit();
}
monitor_info_manager(); // вызвали монитор, в нем как мы знаем произойдут проверки и выполниться либо перехват клавиш, елси окно только развернулось, либо отпускание перехвата, если свернулось
wait(1);
} // конец цикла
}
// конец кода

выводы по этому модулю, подключили и пользуем вызывая функцию show_info, никаких сложностей
опишу как я создаю карты, а если будет интересно, то помогу с кодом.
есть класс клетка, создаётся двумерный массив ссылок на объекты класса клетка.
сам объект клетка содержит в себе местность, она ввиде числа, и объект который на этой клетке может находиться, но об объектах рассказывать тяжело, мы ограничимся местностью
объект клетка может преобразовать себя в строку, также объект который находится на этой клетке тоже может модифицироваться в строчку, а это всё нам нужно чтобы записывать карту в файл
так ввот, у нас есть карта - массив двумерный из клеток, мы меняем на этих клетках местность, какбы рисуем, причем рисовать очень удобно, также ставим на нужных клетках объекты, например дерево
рисуем так, можем выбрать местность которой будем закрашевать, пробелом закрашиваем, а также можем закрашивать целые области, указывая нижний левый и верхний правый угол области
нарисовали сохраняем, создаем объект типа dictionary то есть словарь, впихиваем в него по ключам клетки, вернее клетки преобразованные в строки
ключи это что-то привязанное к координатам клетки
ну например так
dictionary d;
d.set(i+":"+j, map[i ][j].to_string());
первый параметр ключ, второй клетка преобразованная в строку.
словарь заполнили, теперь словарь преобразовываем в строку и если надо эту строку шифруем, как это делается наверняка многие знают.
а строку уже записываем в файл, и я рекомендую в двоичном формате, иначе запись длинной строки происходит не корректно
для открытия карты делаем всё наоборот, и в картографе получаем возможность дорисовывать карту
вобщем создание карт происходит быстро и для этого не нужно быть програмистом, любой человек в вашем картографе сможет быстро создавать сложные карты, а после редактировать
ссылка на картограф и игру в конце, конечно игра демонстрирует только перемещение по карте
попробуйте обязательно, я думаю это зажжёт в вас желание плотнее изучать програмирование, попробуйте хотябы посоздавать карту,

те, кто скачивал, перекачайте, не работали местности, по которым нельзя пройти, в картографе с 23 числа по 36, сейчас поправил.
только объекты в картографе не создавайте, в игре они будут считываться с ошибкой, эксперементируйте с местностью, всего 37 местностей, с 0 до 36

https://yadi.sk/d/d-ShVbittVjuG

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

18 (Wed-10-16 15:12:50 отредактировано la Gata)

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

Приветы!
Bgt хорош, но некоторых важных вещей в нем нёт, расскажу как я создаю приложения с графическим интерфейсом, что необходимо для программ, да и в играх часто используется, например, плэйрум.
Конечно, одним bgt ту не обойтись, но в нём есть возможность использовать dll-библиотеки, через них и будем создавать экран.
Лучшим решением является использование win api, но мне лень это всё изучать, поэтому я взял, всеми забытую delphi 7.
Создал библиотеку и отдельно форму, добавил форму к библиотеке, накидал на неё компоненты.
В библиотеке создал две функции: одна запускает окно, вторая возвращает события окна, пока что только проверка на то, закрыл ли пользователь окно или нет.
Ну и в форме ещё в событии уничтожения окна очищаю память.

Теперь bgt кодим

//main.bgt главный файл проекта

#include "includes/classes/window.bgt"; // подключили класс, в котором описано взаимодействие с окном

Window@ window; // указатель на объект класса Window

void main () {
@window = Window(); // инициализация объекта
window.show_window(); // вызов метода создания окна
while (true) {
if(@window!=null)
window.monitor(); // мониторим состояние окна если оно существует
wait(5);
} // конец цикла
}

// конец файла main.bgt

дальше создаём класс Window, именно он будет пользовать библиотеку, кстати её надо положить в корень программы

// кодим window.bgt

class Window {
library dll; // объект библиотеки
dictionary@ d; // словарь нужен для получения результатов
int hWnd; // пока не применяю, сохраняю сюда дескриптор окна

// конструктор
Window() {
dll.load("window.dll"); // загрузили библиотеку в память
hWnd = 0; // обнулили дескриптор окна
}

// метод запуска окна
void show_window() {
@d =dll.call("int show_form();"); // об этом ниже напишу. это мы вызвали функцию открытия окна из библиотеки, и результат записан в словарь
d.get("1", hWnd); // записали дескриптор
}

// этот метод вызываем из главного цикла программы. сюда будут прилетать события окна
void monitor() {
@d =dll.call("int is_active_window();"); // снова вызов функции из библиотеки, в словаре будут результаты
int i;
d.get("1", i);
if (i<1)
exit(); // если результат меньше одного, а это значит пользователь закрыл окно, то выходим из программы
}

// деструктор
~Window() {
dll.unload(); // выгрузили библиотеку
}

} // конец класса

// конец файла window.bgt

теперь подробнее о вызовах функций из библиотек
@d =dll.call("int show_form();");
call - метод объекта library возвращает словарь с результатами.
принимает в себя обязательно строку - сигнатура функции в библиотеке.
и принимает ещё те данные, которые прописаны в сигнатуре функции.
"int show_form();" - это функция, отдаёт число, не принимает ничего. поэтому у меня тут только один строковойй параметр.

В результате мы получили обычное окно программы с двумя редакторами, открывается оно быстро, никаких нагрузок и задержек нет. дальше творчество.
Если, например, нужна обработка нажатия клавиши энтер на редакторе, то это все прописывается в dll, из bgt мы можем только мониторить.
конечно писать много ещё. это всё только как основа.

Даю исходники bgt,  исходники же библиотеки давать не буду, да и кто хочет может писать библиотеки на чём хочет, тут не принципиально
https://yadi.sk/d/D5sNvc8yw3DDA
Заметьте, что после закрытия окна, закрывается всё корректно, можно отследить из процессов.
На этом всё!

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

19

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

в примере выше есть ошибки. в словарь приходит значение с ключём 0 а не 1. в dll мне пришлось добавлятьпоток. разобрался не сразу. но в итоге есть окно. проекты можно писать с gui. выкладывать не буду. но возможности теперь достаточно расширились в програмировании програм и игр.

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

20

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

Тестирование работы с картами на bgt.
Все замеры производились на слабом процессоре intel atom n2600.
Размер карты для теста взят 550 на 800, то есть 440000 клеток.
Карта типа двумерный массив из целочисленных данных заполняется любыми числами, в моём случае 37 чисел.
все данные вносятся в словарь, который сериализуется и шифруется ключом, после чего строка записывается в файл.
Конечно также заносится размер карты, а во-втором случае ещё местность поумолчанию, ну я во-втором случае ещё сохраняю позицию на карте, чтоб можно было продолжить рисовать от этого места. ну это всё мелочи, там не больше 10 байт.
2 варианта работы с картами.
1. Карта сохраняется путём внесения в словарь ключа, состоящего из координат разделённые слэшем, и значения этих координат, естественно через 2 цикла for.
Данный метод по логике наипростейший, но как оказалось это ужасно долго.
2. Карта сохраняется сложным методом. во-первых есть местность поумолчанию, которая записывается в словарь и которая игнорируется в дальнейшем при сохранении, далее каждая линия карты заносится в соответствующие строковые массивы, а эти строковые массивы закидываются в словарь.
Строковый массив имеет 37 элементов по одной строке на каждую местность, та строка, где должна быть местность поумолчанию не заполняется.
Обрабатываются линии карты поочереди, если в клетке встречается иная местность то она вписывается в соответствующую строку массива, при этом координата по x вписывается 1 раз, потом разделитель знак двоеточие, потом через слэш все координаты по линии y.
В те строки массива, в которые были добавлены значения добавляется разделитель линий карты точка с запятой, и Обработка переходит на следующую линию карты.
Таким образом строка может выглядеть так
1:4/5/6/99/100;2:1/2/3/4/5/99/100;12:1/2/3/4/98/99
В конце точки с запятой нет, их не ставим, иначе карта будет весить на 37 байт больше! (смех)
Вообще алгоритм на языке компьютера сложен, но это не значит что ему надо выполняться больше времени, а совсем наоборот, мы делаем только необходимое, не заполняя  повторяющиеся данные, как например значение x в каждой координате на одной линии.

Кстати, логично предположить, что в первом варианте время сохранения и время загрузки карты будет примерно одинаковое, так как алгоритмы сохранения и загрузки данных аналогичны.
А во-втором варианте можно предположить, что время сохранения будет выше времени загрузки карты, потому что при сохранении считывается вся карта и происходят решения на добавление данных в файл, а при загрузке карта заполняется только согласно добавленным в неёданным, хотя карту можно закрасить всю чем-нибудь, тогда она при загрузке будет заполняться дольше.
то есть, если карта закрашена вся отличной местностью от местности поумолчанию, то время загрузки предположительно будет примерно таким же, как при сохранении
Ещё логично предположить, что в первом случае время тратиться на внесение в словарь данных, там 440000 раз будет внесено в словарь, во-втором случае в словарь заносятся 37 строк, конечно во-втором случае строки заполняются, понятно это занимает время, но словарь, а это хэш-таблица работает медленее чем строки, об этом легко почитать в гугле.

Результаты
А теперь самое интересное. циферки!
Забегая вперёд, скажу, я был сильно удивлен результатами, и очень доволен вторым способом работы с картами в bgt.

Размер карты:
1. 7.49 мегабайт
2 Полностью закрашенная. 2.16 мегабайт
2 Пустая, только местность поумолчанию. 128 байт
Вообще пустые карты любого размера весят 128 байт
Имейте ввиду, карту вряд ли надо будет закрашивать полностью, ну например в основном у нас на карте сделаем землю, а закрасим ну дороги речку здания и прочее нарисуем, но земли будет больше, следовательно карта будет весить меньше чем закрашенная полностью.

Время загрузки карты:
1. От 51 до 54 секунды
2 Полностью закрашенная. около 3,5 секунды, чуть меньше
2 Пустая, только местность поумолчанию. около 0.65 секунды
Если даже полностью закрасить карту, то скорость более чем в 14 раза

Время сохранения карты
1. от 25 до 28 секунд
2 Полностью закрашенная. около 7 секунд чуть больше
2 Пустая, только местность поумолчанию. около 0.8 секунды
Я предполагал в первом случае сохранение должно быть тоже около 52 секунд, оказалось в 2 раза меньше, с чем это связано можно поразмышлять.
Полностью закрашенная карта во втором варианте сохраняется дольше в 2 раза примерно, чем загрузка карты, но нам важнее всего загрузка, игроки будут её загружать. а 3 с половиной секунды на 440000 заполненных клеток, это впечатляющий результат для моего слабенького друга.

Ну и я тут себе немножко карту нарисовал по размеру x y такая же, весит 458 килобайт, то есть нарисовал одну шестую местности, остальное местность поумолчанию
Загрузка её 1300 миллисекунд, сохранение 2200.

Выводы делать не буду, они налицо.
На этом всё.

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

Сообщений с 11 по 20 из 40

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

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

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



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

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