Под такие действия я бы изначально разрабатывал систему с ходами жестко разбитыми на фазы (как в MTG), а не делал костыли из паузы на все приложение.kipar писал(а):Нет, ну не только же дверь открыть.
Скажем, "колдун кастует по вам фаерболл, использовать контрзаклинание? Выберите уровень"
"Гоблин замахивается по вам мечом, использовать контратаку (осталось за ход: 2 из 3)?"
Барионикс 0.5.3a
Модератор: Maelstrom
Re: Барионикс 0.5.3a
- Maelstrom
- Мастер
- Сообщения: 2062
- Зарегистрирован: 26 ноя 2006, 14:19
- Откуда: г. Усть-Кирдык
- Контактная информация:
Re: Барионикс 0.5.3a
Так у меня в прошлом бариониксе и сделано. И чем эта система плоха? Свою задачу - останавливать всю механику игры в абсолютно любом месте - исполняет на всё 100%, безо всяких изращений с измельчением событий.Да, как-то так.
Айв кнгенгах Йог-Сотот
- Cfyz
- Сообщения: 776
- Зарегистрирован: 30 ноя 2006, 10:03
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Барионикс 0.5.3a
Просто это как GOTO или куча голых указателей в C++. Вроде бы сами по себе обычный инструмент, свою задачу выполняют на 100%, но одно их использование — верный признак, что код пошел по бороде или на пути к тому.Maelstrom писал(а):Так у меня в прошлом бариониксе и сделано. И чем эта система плоха? Свою задачу - останавливать всю механику игры в абсолютно любом месте - исполняет на всё 100%, безо всяких изращений с измельчением событий.
Есть архитектурная проблема: у игры должна быть возможность быть поставленной на паузу в любой момент. Идея заблочить UI, навесить глобальных флагов и прокачивать события ввода в двух (трех? десяти?) разных местах, некоторые из которых оказываются рекурсивно связаны — это жутчайший костыль. То, что это именно костыль, а не ловкий хак, легко увидеть выдумав еще какое-нибудь условие — например во время паузы на блок в бою дать возможность открывать окно персонажа и менять местами активные стратегии уклонения или хз что еще. И только не надо про "а мне такое не потребуется", рано или поздно что-то да потребуется, костыль треснет и код рухнет.
К слову, вообще идея блочить UI, где бы то ни было и каким бы то ни было способом — провальна сама по себе. Просто выйти из приложения в любой момент, открыть справку в любой момент, посмотреть окошки логов, персонажа, инвентаря, сделать пометку на карте посередине боя — какого черта это внезапно перестает работать только потому, что произошло какое-то якобы интересное мне событие?
Пытается раскуклиться
- Maelstrom
- Мастер
- Сообщения: 2062
- Зарегистрирован: 26 ноя 2006, 14:19
- Откуда: г. Усть-Кирдык
- Контактная информация:
Re: Барионикс 0.5.3a
Так вешаться должен не УИ, а механика игры (ну, не знаю как назвать ещё). В какой момент ставиться, например, Pause = 1. И пока оно так, обработчик нажатий на кнопки будет принимать только команды, которые не приведут к изменению состояния игры. То есть посмотреть лог сообщений или окно персонажа - это спокойно, а вот сменить тактику или изучать новые навыки - ни за что.
Айв кнгенгах Йог-Сотот
- Cfyz
- Сообщения: 776
- Зарегистрирован: 30 ноя 2006, 10:03
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Барионикс 0.5.3a
Верно, полностью согласен. Нюанс только в подходе к реализации той самой "Pause = 1".Maelstrom писал(а):Так вешаться должен не УИ, а механика игры (ну, не знаю как назвать ещё). В какой момент ставиться, например, Pause = 1. И пока оно так, обработчик нажатий на кнопки будет принимать только команды, которые не приведут к изменению состояния игры. То есть посмотреть лог сообщений или окно персонажа - это спокойно, а вот сменить тактику или изучать новые навыки - ни за что.
Я еще раз акцентирую внимание на том, что если поток один, то малой кровью ты не отделаешься. Для того, чтобы работал интерфейс (как минимум — выход/справка/etc.), нужно, чтобы ввод обрабатывался постоянно. Однако, помимо обработки ввода, есть еще обработка мира, всяких порожденных вводом событий и пр. Фактически, это вся остальная часть программы: между окончанием обработки ввода на текущей итерации и началом следующей обработки на следующей итерации. Вот это опасное место. Для простоты иллюстрации давай завернем всю обработку ввода в ProcessInput, а все остальное — в ProcessWorld:
Код: Выделить всё
while ( running )
{
ProcessInput();
ProcessWorld();
}
Отсюда есть только два выхода:
1. Раздробить обсчет мира на отдельные действия, тем самым дав возможность безболезненно выходить из ProcessWorld не просчитав ход до конца.
2. Сделать обсчет мира во втором потоке, который может быть поставлен на честную паузу независимо от потока UI.
Внимательный читатель может заметить, что выход на самом деле только один, п. 1 является предельно элементарной симуляцией многопоточности.
Ну и справедливости ради,
3. Не использовать механизм паузы в процессе хода.
Но реализация этого пункта не рассматривается как не соответствующая поставленному условию.
Пытается раскуклиться
- Maelstrom
- Мастер
- Сообщения: 2062
- Зарегистрирован: 26 ноя 2006, 14:19
- Откуда: г. Усть-Кирдык
- Контактная информация:
Re: Барионикс 0.5.3a
Я тебя немного не понимаю. Рогалик - игра пошаговая, любые изменения состояния игры могут происходить ТОЛЬКО в результате нажатия кнопок. Поэтому мы имеем скорее ProccessInput и DrawFrame - второй тупо рисует картинку, которая изменяться не должна (анимация всяких эффектиков, допустим, идёт по своему закону, и, если состояние игры не изменилось, будет идти также неизменно).
В недрах кода, когда надо делать паузу, ставим следующее:
При этом по условию DrawFrame никак игру не изменяет, а ProcessInput в состоянии паузы игнорирует все команды, которые могли бы привести к изменению состояния игры.
В недрах кода, когда надо делать паузу, ставим следующее:
Код: Выделить всё
pause = 1;
while (pause == 1)
{
ProcessInput();
DrawFrame();
}
Айв кнгенгах Йог-Сотот
- Cfyz
- Сообщения: 776
- Зарегистрирован: 30 ноя 2006, 10:03
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Барионикс 0.5.3a
В принципе, это и есть тот костыль, про который я говорил. Обработка ввода, внутри которого обсчет, внутри которого обработка ввода.
1. Будет работать до того момента, пока однажды не потребуется таки изменить состояние внутри паузы. Механизм-то один, а пауз может оказаться много: сегодня только <еще>, завтра пауза на блок, послезавтра в блоке можно выбрать действие. Решается волевым отказом от шанса на реализацию таких фич.
2. Должно соблюдаться условие согласованности всего влияющего на отображаемую информацию состояния игры перед любой паузой, что может стать неудобно. Не решается никак, с этим придется жить.
Ну то есть рано или поздно оно аукнется. Но поскольку похоже, что ты понимаешь, на что идешь (а не просто заблуждаешься, как я подумал вначале), вынужден оставить филосовскую часть дискуссии и это решение за тобою >_<.
По сугубо технической части, подобный трюк с обработкой внутри обработки прокатит не всегда. Консоль/BearLibTerminal и, возможно, SDL такое простят; HGE и похожие движки, WxWidgets и прочие окошки — черта с два. Ты что в итоге выбрал-то?
1. Будет работать до того момента, пока однажды не потребуется таки изменить состояние внутри паузы. Механизм-то один, а пауз может оказаться много: сегодня только <еще>, завтра пауза на блок, послезавтра в блоке можно выбрать действие. Решается волевым отказом от шанса на реализацию таких фич.
2. Должно соблюдаться условие согласованности всего влияющего на отображаемую информацию состояния игры перед любой паузой, что может стать неудобно. Не решается никак, с этим придется жить.
Ну то есть рано или поздно оно аукнется. Но поскольку похоже, что ты понимаешь, на что идешь (а не просто заблуждаешься, как я подумал вначале), вынужден оставить филосовскую часть дискуссии и это решение за тобою >_<.
По сугубо технической части, подобный трюк с обработкой внутри обработки прокатит не всегда. Консоль/BearLibTerminal и, возможно, SDL такое простят; HGE и похожие движки, WxWidgets и прочие окошки — черта с два. Ты что в итоге выбрал-то?
Пытается раскуклиться
Re: Барионикс 0.5.3a
На самом деле, есть простой способ реализации этой фичи. Никакая анимация не страдает.
Называется - модальные окна.
Т.е. мы в любой функции можем вызвать if dialog.showmodal = mrYes then ..., это вызовет окно, причем лежащее позади него окно будет продолжать анимированно работать. А в диалоге можно отобразить и другие окна, как модально так и немодально.
Вместо окна можно просто вывести <more>, мы ведь не виндовый механизм а свой используем, т.е. окно - абстрактная вещь, а не область на экране с рамкой.
Теперь - о том как это реализовать. Собственно, я у себя уже так сделал, просто как-то не задумывался. Суть проста - цикл обработки сообщений и находится в show_modal.
В абсолютно любой точке этого цикла можно вызвать Dialog.show_modal, который выглядит точно также. Если в процедуре update_screen обновлять не только текущее, но и вышележащие окна, то анимация будет продолжаться. По возврате из show_modal продолжится обработка предыдущего цикла.
Ну а при запуске игры мы просто вызываем MainUI.show_modal, он и выполняет роль основной игры.
Называется - модальные окна.
Т.е. мы в любой функции можем вызвать if dialog.showmodal = mrYes then ..., это вызовет окно, причем лежащее позади него окно будет продолжать анимированно работать. А в диалоге можно отобразить и другие окна, как модально так и немодально.
Вместо окна можно просто вывести <more>, мы ведь не виндовый механизм а свой используем, т.е. окно - абстрактная вещь, а не область на экране с рамкой.
Теперь - о том как это реализовать. Собственно, я у себя уже так сделал, просто как-то не задумывался. Суть проста - цикл обработки сообщений и находится в show_modal.
Код: Выделить всё
class UI
def show_modal
while getkey
process_key
end
process_mouse
update_screen
end
end
Ну а при запуске игры мы просто вызываем MainUI.show_modal, он и выполняет роль основной игры.
- Maelstrom
- Мастер
- Сообщения: 2062
- Зарегистрирован: 26 ноя 2006, 14:19
- Откуда: г. Усть-Кирдык
- Контактная информация:
Re: Барионикс 0.5.3a
Этого не потребуется в принципе. Выбор действия, равно как и (Y/N) и даже фраза в ответ на "What do you wish for?" - это ввод со стороны пользователя, и в коде вместе со снятием паузы будет сохранение этого ввода в какую-нибудь переменную, а потом уже, после паузы, с этой переменной что-нибудь сделать можно будет.1. Будет работать до того момента, пока однажды не потребуется таки изменить состояние внутри паузы. Механизм-то один, а пауз может оказаться много: сегодня только <еще>, завтра пауза на блок, послезавтра в блоке можно выбрать действие. Решается волевым отказом от шанса на реализацию таких фич.
С этим проблем вообще не вижу. Информация о отоброжаемых на экран тайлах уже в старом бариониксе жила своей жизнью, к этому ещё кое-что прибавиться, всякие надписи и т.д., которые в ВБ тупо задавались в форме. Но в целом никаких сложностей не предвижу.2. Должно соблюдаться условие согласованности всего влияющего на отображаемую информацию состояния игры перед любой паузой, что может стать неудобно. Не решается никак, с этим придется жить.
Ну то есть рано или поздно оно аукнется. Но поскольку похоже, что ты понимаешь, на что идешь (а не просто заблуждаешься, как я подумал вначале), вынужден оставить филосовскую часть дискуссии и это решение за тобою >_<.
У меня ж таким макаром уже было всё реализовано, я с дуру решил, что такое без виндусовских окошек и фреймворков не реализовать
Впрочем, в ходе дискусии ещё несколько тонкостей для себя отметил.
Да я пока сам не знаю, пощупаю наверное первым делом SDL.По сугубо технической части, подобный трюк с обработкой внутри обработки прокатит не всегда. Консоль/BearLibTerminal и, возможно, SDL такое простят; HGE и похожие движки, WxWidgets и прочие окошки — черта с два. Ты что в итоге выбрал-то?
Что-то я ниччего не понимаю. Что за окно, которого на самом деле нет?Называется - модальные окна.
Айв кнгенгах Йог-Сотот
Re: Барионикс 0.5.3a
Ну т.е. есть базовый класс (пример буду на ruby давать, т.к. в С++ что-нибудь напутаю).Maelstrom писал(а):Что-то я ниччего не понимаю. Что за окно, которого на самом деле нет?
Код: Выделить всё
class Window
def show_modal
@visible = true
while not closed
Poll_SDL_Event...что-то-там
process_keys
process_mouse
update_screen
end
end
end
Код: Выделить всё
class MainUI < Window
def process_keys
if keys.include? kbUp then
player_go_up
elsif...
end
end
def process_mouse
...
end
def update_screen
draw_background
process_animations
draw_player
log.update
...
end
end
А AskBlock - другой потомок Window:
Код: Выделить всё
class AskBlock < Window
def process_keys
if keys.include? 'Y' then
modal_result = :Yes
close_modal
elsif...
end
end
def process_mouse
return false
end
def update_screen
MainUI.update #это конечно для этого примера, на самом деле там будет что-то типа "обновить все предыдущие окна"
show_text "Заблокировать удар гоблина? Y/N", x, y, color::red
end
end
- Jolly Roger
- Сообщения: 2973
- Зарегистрирован: 27 ноя 2009, 09:10
- Откуда: Minsk, Belarus
Re: Барионикс 0.5.3a
Писать диздок спустя несколько лет разработки и множества изменений концепции - исконная русская девелоперская традиция.
- Cfyz
- Сообщения: 776
- Зарегистрирован: 30 ноя 2006, 10:03
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Барионикс 0.5.3a
Jolly Roger
Ну, помимо шуток, тут вроде бы проскальзывали аргументы вида "стал программистом" и "смотреть на востребованность". Но так как ничего конкретного озвучено все же не было, затаился и слежу за темой -- сам-то я люто, бешено люблю С++.
Ну, помимо шуток, тут вроде бы проскальзывали аргументы вида "стал программистом" и "смотреть на востребованность". Но так как ничего конкретного озвучено все же не было, затаился и слежу за темой -- сам-то я люто, бешено люблю С++.
Пытается раскуклиться
- Uvadzucumi
- Сообщения: 365
- Зарегистрирован: 29 ноя 2011, 07:13
- Откуда: Дубай, ОАЭ (Минск, Беларусь)
- Контактная информация:
Re: Барионикс 0.5.3a
тут имеются ввиду конструкции вида?:Cfyz писал(а):сам-то я люто, бешено люблю С++.
Код: Выделить всё
auto it = std::find_if (m_controls.begin(), m_controls.end(), [&] (Module * mod) { return mod == 0; });
Меня окружали милые, добрые люди... медленно сжимая кольцо
- Jesus05
- Сообщения: 1840
- Зарегистрирован: 02 дек 2009, 07:50
- Откуда: Норильск, сейчас Санкт-петербург.
- Контактная информация:
Re: Барионикс 0.5.3a
Это уже не С++ это уже С++11
тем более это просто одна из возможностей. врядли сильно применяемая в программировании в больших командах.
тем более это просто одна из возможностей. врядли сильно применяемая в программировании в больших командах.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 21 гость