- Сообщений: 1597
- Спасибо получено: 1522
[VX Ace] О пользе вызова скрипта
И так, давайте представим, что во время работы над нашим проектом, нам понадобилось точно узнать чему ровна конкретная переменная и, в зависимости от каждого значения предпринять определённые действия. Например,у нас есть NPC, который спрашивает сколько нужно создать деревьев.
Как видите, ветвлений условий не так много, а их список уже уходит куда-то вниз. Но что же делать? Смириться и копаться в этих вложенных условиях до умопомрачения? Или же отбросить идею? Есть более удачное решение! При помощи конструкции case, которую я опишу ниже, мы можем привести всё в аккуратный вид.
Что же нам для этого понадобится? Немного логического мышления и чуток старания. Использовав это, мы получаем следующее:
Конечно, это не оптимально, но позволило нам скомпоновать всё более удачно. Рассмотрим, что же для этого нужно было сделать.
- Заглядывая в подсказку выше, мы находим нужные аналоги наших команд.
- Пишем их по порядку выполнения.
- ...
- Profit!
Вот такой код получился у меня:
Для удобства его чтения, я добавил пробелы отделяющие разные конструкции и комментарии(фразы после "#") внутри самого кода. Единственной проблемой при таком подходе может стать то, что поле для ввода скриптов ограничено, однако при рациональном подходе это не составит проблем. Например, мне понадобилось два раза задействовать эту команду, однако это добавило лишь больше наглядности. В первом вызове идёт работа с переключателями, а во втором мы создаём диалоговые окна с ответами.
Далее я прилагаю наглядную схему того, как выглядят использованные команды в скриптовом виде.
Так же, прикладываю демо проекта с двумя вариантами обработки. Скачать демо с ЯД.
Пожалуй, на этом всё. Надеюсь это хоть кому-то да поможет.
Если вдруг возникнут вопросы, я с радостью отвечу на них. Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
А в самом тельце события, для выбора реплики, впихаем это:
Что же касается обнуления собственных переменных, то тут тоже можно сократить, примерно так:
Диапазоны можно создавать динамически, в кейсах смысла особо нет.
P.S. Совсем забываю, что в серьезных языках есть взятие элемента из массива со значением по умолчанию, так что для выбора реплики используем fetch и сократим количество кода
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Жуть болотная, на лапках, в тапках и с пулемётом...
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 1597
- Спасибо получено: 1522
Не давно, для проекта на готв, я написал небольшую систему бросания динамита. На её примере и будет построена эта статья. Однако оговорюсь сразу, что тут мной были использованы несколько скриптов, но в целом они не так важны. Скрипт на локальные переключатели и, скрипт с которым мне помог Липтон:
Думаю, как реализована возможность положить динамит, понять легко, но всё же поясню немного:
Что тут собственно происходит? Первыми двумя строчками, мы приводим событие в нужное нам положение.
$game_map.events[$tnt_id].set_direction(2) - заставляет ивент с указанным id встать лицом вниз(ибо именно в таком положении динамит не зажжён в моём чарсете). Так же есть варианты: 4: влево, 6: вправо, 8: вверх.
$tnt_id - это глобальная переменная, которую я заранее объявил в скриптах. Вы можете с таким же успехом использовать и $game_variables[n], просто мне не хотелось лишний раз их трогать.
Switch_Core.turn_on($tnt_id,"A") - команда скрипта, на локальные переключатели. Собственно, она включает локальный переключатель "А", для указанного ивента. На странице с которым и описаны все возможности взаимодействия.
Ну и, главное, в конце не забыть уменьшить число динамита у нас в кармане на 1, это можно сделать командой ивента. Собственно, теперь, когда мы научились класть динамит, приступим к более сложной процедуре. К его броску.
Что бы понять, что происходит выше, нам надо ответить себе на вопрос: "Что происходит, когда мы что-то бросаем?". Всё верно - предмет летит с заданной нами силой и падает. А если встречает стену, то ударяется об неё и остаётся там, конечно же можно ещё и сделать что бы при ударе о стену объект летел обратно по инерции, но я не стал заморачиваться. Так же, эта команда не рассматривает вариант столкновения с ивентами, к сожалению.
Но рассмотрим подробнее сам код. Так-как начальная точка полёта, это местоположение игрока, то мы должны переместить ивент на его клетку. Строки: x = $game_player.x и y = $game_player.y, позволяют нам записать в локальные (то есть уникальный для этой команды вызова скрипта и не доступные больше ниоткуда) переменные позицию игрока по x и y.
Дальше, мы, используя уже записанные координаты, перемещаем ивент на позицию игрока и задаём ему графику динамита:
Используя, уже знакомую нам конструкцию case, определяем в какую сторону смотрит игрок и куда он, соответственно, бросит динамит. Однако, кроме задать направление полёта, мы должны задать его траекторию. И, в зависимости от того, как близко игрок будет к непроходимому участку, надо поменять эту самую траекторию (естественно, с точки зрения логики, траектория должна изменяться непосредственно во время полёта, но об этом как-нибудь в другой раз). Рассмотрим вариант, с положением игрока лицом вниз. Для этого есть такая строчка: i -= 1 until $game_map.check_passage(x, y+i, 0xF), где i - это объявленная чуть выше локальная переменная со значением три. Until же, это конструкция, на вроде case, только работающая несколько другим способом. Обычно, она выглядит почти как Case:
Например:
Однако, внутри моего вызова используется модификатор until. Его удобно использовать, если надо выполнить всего одну команду внутри проверки.
Например:
Найдя клетку, в заданном диапазоне, куда может приземлиться динамит, мы отправляем его в полёт, командой прыжка ивента: $game_map.events[$tnt_id].jump(0, i).
Сделав всё это, мы, опять же используя команду из скрипта на локальные переключатели, включаем страницу с переключателем "B", где уже и описываем сам взрыв.
Что бы не загружать лишний раз систему, сам взрыв я реализовал по средствам заданного у ивента маршрута. Там нас интересуют опять же, строки вызова скрипта. Их пять:
$deev_x = $game_map.events[1].x - записывает в глобальную переменную координату x ивента с указанным номером (опять же, тут можно использовать и $game_variables, если вы не хотите заморачиваться с объявлением собственных переменных).
$deev_y = $game_map.events[1].y - делает то же, для координаты у.
$game_map.events[1].moveto(22, 15) - перемещает в сторону "взорвавшийся" ивент.
$game_temp.reserve_common_event(5) - вызывает глобальный ивент, где обрабатываются последствия взрыва.
Switch_Core.toggle(1,"B") - выключает локальный переключатель "В" у ивента, что автоматически возвращает его на пустую страницу.
А вот, что внутри глобального ивента, что должен обработать последствия взрыва:
x = $deev_x и y = $deev_y в данном случае, строки нужные лишь для удобства работы дальше. В принципе, мы могли бы использовать и значения из глобальных переменных, но у локальных просто название короче.
for e in [x+1, x-1, x] - эта строка поочерёдно задаёт переменной значения внутри квадратных скобок и выполняет команду дальше.
for i in [y+1, y-1, y] - делает то же и самое, а так как она внутри предыдущей команды, то мы получаем блок из координат, примерно такого вида:
id = $game_map.event_id_xy(e, i) - одновременно объявляет новую локальную переменную и задаёт ей значение id ивента, по координатам.
Switch_Core.toggle(id,"A") if $game_map.events[id].event.name == "block" - проверяет имя ивента, если оно соответствует тому, что нам нужно, то активирует локальный переключатель A у ивента с объявленным ранее id.
if id != 0 - спасает от ошибки, в выше описанной строке, если ивента в координатах не оказалось.
В общем, на этом в целом-то всё. Более подробно можно посмотреть в демке, доступной по старой ссылке и тут. События камней я специально немного переписал, что бы можно было вернуть их обратно. Это вызвало небольшой графический косяк, но он не характерен для рабочей версии ивентов, так что можно не волноваться об этом.
Засим, откланяюсь и попрошу писать комментарии в случае если что-то будет непонятно или есть предложения по улучшению.
P.S. Рекомендую так же ознакомиться с разделом "управляющие структуры" в русско язычной справке по VX Ace, которую можно найти по ссылке у меня в подписи.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 1597
- Спасибо получено: 1522
Товарищ, yuryol в чате задал любопытный вопрос и, ища ответ на него, я решил немного поэкспериментировать.
Первым делом, мне пришла в голову идея, проверить то, в чём был уверен в общем-то давно.
Консоль ответила мне положительно.
Отсюда следует вывод, что мои мысли были верны. Как и все остальные переменные на ruby, переменные из класса Game_variables являются массивом. Это означает, что к ним применимы все методы, которые применимы к прочим массивам(читай справку, раздел Array).
Более того, написав такие строки:
И даже сможем вывести на экран сообщение с этой переменной. Указав команду "\V[13]" в диалоге!
Я не придумал каких-то особо практичных методов использования этого, предлагаю сделать это самостоятельно. ;ь Но замечу, что в отличие от обычных массивов, которые мы можем объявить в скриптах, эти сами записываются в файл сохранения.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
forums.rpgmakerweb.com/index.php?/topic/...nced-game-variables/
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 1597
- Спасибо получено: 1522
DK пишет: Не совсем верно то, что переменные являются массивом. Своим первым действием ты присвоил переменной объект типа массив, но до этого ты не смог бы применить методы массива к данной переменной. Ruby - динамический язык, в котором нет строгой типизации, поэтому любой переменной можно присвоить любой тип данных.
Спасибо!
Амиф мне пояснил, а ты грамотно сформулировал, а то я никак не мог точно выразить суть. @^~^@ Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Iren_Rin пишет: так как встроенного присвоения значения переменной к координате эвента я не нашел
А в МВ есть
Если я правильно понял твой пост.
Спрошу здесь,так как чатик щас беснуется, да и чтоб, если есть решение, то оно "увековечилось".
Дано: В общем есть летящий объект (камень, пуля, стрела, давящая всех машина). Допустим это событие с id=11. И это событие параллельно.
Есть десять событий, пусть их id будет с 1 по 10.
Надо через стандартную ивентовую команду "ветвление условий" вписать проверку координат этого летящего события с координатами остальных 10-ти событий. И если координата летящего объекта совпадает то например выводим анимацию взрыва/крови
Решение
$game_map.events[n].x - координата события по х, $game_map.events[n].y - по у.
пишем в графе "скрипт" ветвления следующую строку:
В общем вот и всё, всё работает, но НЕУДОБНО,НЕКРАСИВО,ЗАПУТАННО
есть ли способ как-то сократить эту запись?
ВОЗМОЖНЫЕ РЕШЕНИЯ
так как можно сделать массив то пишем
Последний мой вариант
В общем, есть ли какой-либо способ?
Конечно, можно сделать как в твоем прошлом посте, если опять же я парвильно тебя понял, и записать эту фразу во все 10 событий, но тогда будет куча параллельных событий, а это не есть хорошо
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Тоже самое, что и у Ирена
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Все-таки свитчи использовать не очень хочется,пусть даже локальные если ставить,и так хватает куч переключателей в событиях(
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Paranoid пишет:
Code:$game_self_switches[[map_id, event_id, 'N']]
Да я знаю как селф-свитчи ставить. Но как я уже сказал "все-таки свитчи использовать не очень хочется,пусть даже локальные если ставить"
Думал может именно в ветвлении можно че-нить написать дабы удобнее было
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Юрол хочет это засунуть в стандартное условие в мейкерских эвентах. Только я не понимаю, в чем проблема - записать результат в свитч и проверить его в условии. Один несчастный свитч. Ты его можешь использовать во всех таких эвентах, просто обнуляй его всегда перед вызовом скрипта, или в самом скрипте обнули. Разницы то нет, параллельные эвенты все равно перебираются по-порядку и в основном потоке.DK пишет: Напиши в условии вызов функции, а функцию в скриптах, которая возвращает true или false. В функции будет либо код ирена, либо мой.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Лучше всего сделать функции параметр типа массив, в котором будут содержаться номера событий, которые нужно проверить. Так функцию можно будет вызывать из разных событий. Если это вообще необходимо.
Скрипншот:
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
В сообщении выше вместо текста пишешь: check_event(N, [N1, N2...NN])
N - номер этого события, N1, N2...NN - номера событий через запятую в скобках
Если нужно узнать номер события, которое попало в условие, то вместо true возвращаешь id, а вместо false -1 и уже в самом условии проверяешь
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
