Когда-то давно мне надо было написать функцию, которая двигала бы героя или событие по определенному маршруту. Тогда мне помог ДК, быстренько ее набросав. Правда для героя она не сильно помогала - после заданного маршрута он останавливался и не двигался. ДК тогда был занят, я разобраться не смог, в итоге благополучно на это забил.
НЕДАЛЕКОЕ ПРОШЛОЕ (несколько месяцев назад):
С тех пор прошло много времени, и вот пару месяцев назад снова потребовалось задавать маршрут, но чисто для событий. Я с этим благополучно справился, позабыв, что изобретаю велосипед, который мне состроил ДК еще полтора года назад.
НАШИ ДНИ (в промежутке с 23:00 до 01:00 следующего дня):
А вот дело опять коснулось маршрута героя, то поймал тот же баг. Тут-то я и вспомнил ту функцию ДК. Достав со старого диска запылившийся плагин от ДК, я решил покопаться в именно в нем, благо он был красивее и универсальнее моего.
Спустя часа два наконец понял, как исправить ту ошибку. Надо всего лишь добавить в конец маршрута команду "окончание маршрута"(ROUTE_END), которая делает параметр _moveRouteForcing равным "false" и позволяет герою дальше вершить свои дела:
PHP код:
route.list[amount] = {code: gc.ROUTE_END};
Ну и добавил параметр, который скипает движение, если впереди непроходимый тайл или событие:
PHP код:
route.skippable = true;
Проблемы остались. Например, при присвоении маршрута событию свой прежний маршрут он забывает. В принципе не беда: сохраняем маршрут в переменную, а потом после завершения маневра опять присваиваем событию первоначальный маршрут. Хотя, может есть вариант элегантнее?
Итак, вызов плагина для задания маршрута событию,герою:
PHP код:
$gameMap.moveEvent(id, direction, amount);
, где id - номер события (или 0, если нужен герой), direction - направление, amount - количество повторений (например шагов)
Сама функция:
PHP код:
Game_Map.prototype.moveEvent = function(id, direction, amount) {
if (id) {
var event = this.event(id);
}else {
var event = $gamePlayer;
};
if (!event) return;
var gc = Game_Character;
var route = { list: [] };
var code;
switch(direction){
case 0:{
code = gc.ROUTE_END;
break;
}
case 2:{
code = gc.ROUTE_MOVE_DOWN;
break;
}
case 4:{
code = gc.ROUTE_MOVE_LEFT;
break;
}
case 6:{
code = gc.ROUTE_MOVE_RIGHT;
break;
}
case 8:{
code = gc.ROUTE_MOVE_UP;
break;
}
case 12:{
code = gc.ROUTE_MOVE_FORWARD;
break;
}
}
for(var i = 0; code && i < amount; i++){
route.list[i] = { code: code };
}
Возможность события с приоритетом "под персонажем" или "над персонажем" проходить сквозь другое событие.
Когда еще был на эйсе не очень понимал, почему сделано так, что например событие птица не может пролететь над лошадью.
Случай с приоритетом "Под персонажем" более понятный: те же двери в таком случае будут пропускать события "под персонажем". Но особой надобности ставить этот приоритет событию не особо вижу, кроме как дать другим событиям проходить над ним.
Как известно, при указания в маршруте события движения "вперед", событие будет двигаться только туда, куда оно направлено. При этом команд "повернуться по-диагонали" нет, хотя движение по-диагонали задать можно.
Функция ниже исправляет этот недочет. Теперь можно задать событию "поворот по-диагонали" в маршруте движения через скриптовую команду:
Бывает, что после загрузки новой карты требуется сделать постоянно одно и тоже. Например, обнулять одни и те же переменные или проверять день или ночь в игре. Вместо того, чтоб на каждую новую карту вставлять автособытие, можно просто всё это добавить в скрипт:
PHP код:
var YuryolStart = Scene_Map.prototype.start; Scene_Map.prototype.start = function() { YuryolStart.call(this); //вставляем что хотим: $gameVariables.setValue(1, 0); //например, обнуляем 1-ую переменную };
Недавно наткнулся на статью про очередной фреймворк JS по названием Imba. Сначала приводится примеры кода на JS, а затем то же самое на этом очередном фреймворке:
Спойлертык:
Ниже показана простая JS-функция, которая возвращает наибольшее из двух переданных ей чисел, или, если эти числа равны, значение false.
PHP код:
function findGreatest(num1, num2) { if (num1 > num2) { return num1 } else if (num2 > num1){ return num2 } else { return false } }
Затем, соответственно, автор указывает на преимущества Imba перед чистым JS:
- длинное слово "function",
- куча скобок,
- частое употребление return
То ли автор знает только основы синтаксиса JS, причем устаревшие, и не знает как переписать функцию с учетом его требований. То ли пытается ввести людей заблуждение (хотя делать это на хабре довольно глупо).
Чтобы подобных заблуждений о длине кода JS не было, давайте немного потренируемся в том, как сделать функцию проще, понятнее и читабельней
Сокращение кода
1. if...else
Давайте и начнем с вышеупомянутой функции и попробуем ее сократить:
PHP код:
function findGreatest(a, b) { if (a > b) { return a } else if (b > a){ return b } else { return false } }
1) Выражение в скобках состоят из одной строки, а потому мы их можем убрать:
PHP код:
function findGreatest(a, b) { if (a > b) return a else if (b > a) return b else return false }
2) Избавляемся от "else". Зачем они здесь, если return и так не дает пройти дальше?
PHP код:
function findGreatest(a, b) { if (a > b) return a if (b > a) return b return false }
3) Используем сокращенную запись конструкции if...else, тем самым оставив один return
PHP код:
function findGreatest(a, b) { return (a > b) ? a : (b > a) ? b : false }
4) Знак ">" выше по приоритету, чем "?", а потому мы можем опустить скобки
PHP код:
function findGreatest(a, b) { return a > b ? a : b > a ? b : false }
5) Перепишем ее как анонимную функцию, т.е. записав в переменную
PHP код:
const findGreatest = function(a, b) { return a > b ? a : b > a ? b : false }
6) Это позволит следующим шагом записать ее как стрелочную функцию, т.е. избавившись от длинного ненавидимого некоторыми программистами слова "function"
PHP код:
const findGreatest = (a, b) => { return a > b ? a : b > a ? b : false }
7) Еще одно преимущество стрелочной функции - возможность убрать return совсем, для чего мы должны написать функцию в круглых скобках
PHP код:
const findGreatest = (a, b) => (a > b ? a : a < b ? b : false)
Спойлертык:
8) Чисто для справки - в круглых скобках мы можем писать не только одну строку. В ней мы можем написать и несколько строк, отделяя их запятыми, например можем добавить строчку "a = a/b".
PHP код:
const findGreatest = (a, b) => (a = a/b, a > b ? a : a < b ? b : false)
9) Читаемость конечно упадет, но для пары строк несильно. Если строк больше, можем перенести на несколько строк, как обычную функцию
PHP код:
const findGreatest = (a, b) => ( a = a/b, a > b ? a : a < b ? b : false )
Таким образом первоначальную функцию мы сократили до одной строки. Удобно ли для него это или нет - выбор автора, а выбора, как видим, немало. Лично мне нравится 2 вариант как самый читаемый и 7 - как самый короткий.
2. Switch
Одна из самых непривычных конструкций js. Многими считается устаревшей, кажется чужеродной, а постоянные вставки "break" бесят чуть ли не всех. Тем не менее в том же мейкере он часто используется для считывания направления персонажа. К примеру в этом посте используется подобная функция:
PHP код:
const move = function (direction) { let code; switch(direction) { case 2: code = 'Game_Character.ROUTE_MOVE_DOWN'; break; case 4: code = 'Game_Character.ROUTE_MOVE_LEFT'; break; case 6: code = 'Game_Character.ROUTE_MOVE_RIGHT'; break; case 8: code = 'Game_Character.ROUTE_MOVE_UP'; break; } return code }
1) Мы конечно можем записать брейки в одну строчку, при этом читаемость упадет не сильно
PHP код:
const move = function (direction) { let code; switch(direction) { case 2: code = 'Game_Character.ROUTE_MOVE_DOWN'; break; case 4: code = 'Game_Character.ROUTE_MOVE_LEFT'; break; case 6: code = 'Game_Character.ROUTE_MOVE_RIGHT'; break; case 8: code = 'Game_Character.ROUTE_MOVE_UP'; break; } return code }
2) Но можно вообще отказаться от свитча и использовать объект
Чем хорошо JS? Тем, что синтаксис дает выбор писать так, как нравится. Можно писать в одну строчку, а можно топорно но читаемо. Можно через стандартные старые конструкции, а можно через функции. Это я еще не говорил о "new Function", о котором можно почитать самостоятельно
Чтобы при увеличении окна игры или развороте ее на весь экран не было мыла, вставляем между тегов <head> и </head> в файл index.html в корневой папке игры следующую строчку:
Подсказал Dirge здесь же на форуме, дублирую чтоб не потерять. Подойдет для пиксельных игр. Стоит учитывать, что шрифт также станет рендериться по другому, а потому лучше заменить его на более "квадратный", а в идеале опять же пиксельный.
Пример (слева с вставкой этой строчке, справа - с обычным рендерингом. Мыло справа видно невооруженным глазом):
Можно сделать то же самое, только не через ид события, а через note, например?
Потому что на каждой карте одно и то же событие может иметь уникальный ид, в зависимости от того, в каком порядке оно было создано!
К примеру, я хочу сделать чтобы при нажатии на Z игрок бил кулаком, а враг является параллельным событием в котором находится его интеллект. Для этого я создаю событие на карте,
которое является маской столкновения и перемещается к игроку, каждый раз когда игрок нажимает на Z. Но мало того, у каждого врага свой уникальный ид, так еще и у маски столкновения так же! Если бы можно было сделать проверку столкновения по имени события или тегу, было бы намного проще такое реализовать.
Есть еще такой код, как раз таки проверка столкновения событий:
Можно сделать то же самое, только не через ид события, а через note, например?
Потому что на каждой карте одно и то же событие может иметь уникальный ид, в зависимости от того, в каком порядке оно было создано!
К примеру, я хочу сделать чтобы при нажатии на Z игрок бил кулаком, а враг является параллельным событием в котором находится его интеллект. Для этого я создаю событие на карте,
которое является маской столкновения и перемещается к игроку, каждый раз когда игрок нажимает на Z. Но мало того, у каждого врага свой уникальный ид, так еще и у маски столкновения так же! Если бы можно было сделать проверку столкновения по имени события или тегу, было бы намного проще такое реализовать.
Есть еще такой код, как раз таки проверка столкновения событий:
Здесь тоже требует ИД, что совсем не удобно! Можно ли избавиться от этой ИД зависимости?
да,конечно, надо просто найти ИД события у которого "нот" такой какой нам нужен
1) берем заметку события. на первой странице этой темы уже есть ее код - $gameMap.event(ИД).event().note.contains('имя ')
2) теперь нам надо пройтись по всем событиям на карте и найти ИД события, у которого note равно нужному. все события на карте - если не ошибаюсь $gameMap.event().length , поэтому через любой цикл, напрмиер через тот же for находим ИД
3) теперь вставляем полученный ИД в функцию телепортации
получится че-то типа
var id = function() {
for (let i=0; i<$gameMap.event().length; i++) {
if ($gameMap.event(i).event().note.contains('имя') ) return i;
}
}
$gameMap.event(id).setPosition($gamePlayer.x, $gamePlayer.y);
пишу с работы поэтому возможны глупые ошибки в коде
Я не совсем хорошо шарю в коде, поэтому хочу уточнить некоторые моменты.
1) $gameMap.event(ИД).event().note.contains('имя ') Это нужно сделать перед скриптом, который ниже?
И проверяет оно только наличие события на карте, так? Можно ли проверить наличие события с тегом в игре вообще?
Я использую Yep. event spawner и event copier плагины, события которые я обычно копирую или спавню, находятся на отдельных картах.
2) Меня так же интересует не только setPosition, но и сравнение координат двух событий, через notetag.
Например, если событие 'такое-то' равно координатам другого события, то.
Мне нужно еще понять, в каком порядке писать скриптовые команды. О команде $gameMap.event(ИД).event().note.contains('имя ') я знаю, но я не знаю как она работает и когда применяется. Обычно, когда я самостоятельно пытаюсь что-то написать, на основе тех команд, которые уже знаю, - ничего не получается. Потому что я не знаком с синтаксисом когда и не знаю, что и в каком порядке надо проверять и делать, и какие циклы, функции вообще есть. Конечно, очень рад бы был научиться в этом хоть немного разбираться.
Больше количество разных штук я могу реализовать и на ивентах, но все упирается в координаты и ИД событий, как правило. Проблемы зачастую с ид, и координатами. :<
Древнее зло вновь пробудилось, чтобы оккупировать раздел помощи...
Социальные закладки