Войти на сайт
×
|
ТЕМА: Покодим (уроки программирования для RPG maker MV)
Покодим (уроки программирования для RPG maker MV) 6 года 2 дн. назад #107204
|
Вместо предисловия:
По образованию я экономист, компьютер у меня появился в 18 лет, а кодить я начал летом 2016-ого года. А потому, хоть и работаю в данный момент программистом (на полумертвом языке Делфи), много чего сам не понимаю и постоянно прошу помощи то у одного, то у другого. С одной стороны, вполне могу научить чему-то неправильно. С другой стороны - объяснять я буду довольно простым языком, которые поймут даже совсем новички. Просто потому что говорить правильным "программистским"" языком еще не научился. С чего начать? (для тех, кто совсем ничего не знает) В RPG maker MV язык javaScript. А потому начать надо именно с его основ. Сейчас информации в интернете столько, что найти можно всё. А так как в интернете есть ВСЁ, то найти что-то действительно хорошее всё сложнее 1) Я бы посоветовал начать с сайта "CodeAcademy" Объясняется всё довольно понятно, а главное, что после каждого урока с теорией следует практическая часть, где вы сможете закрепить знания написанием кода прямо на сайте. После прохождения всего курса вы вполне можете начинать писать плагины, а значит перейти к моим урокам ниже. 2) То же самое, только на мобильнике - "sololearn" Больше, чем просто самоучитель. Здесь можно "баттлиться" знаниями с другими пользователями, смотреть размещенный чужой код и прокачиваться прямо как в РПГ 3) Отличный сайт, который многие используют и тогда, когда уже работают программистами learn.javascript.ru . Своего рода самоучитель-справочник, на который вы еще не раз наткнетесь, когда будете гуглить то, что уже позабыли. В конце каждого урока практические задания, некоторые довольно сложные. Очень полезны комментарии пользователей, лучше их почитать хотя бы первые 20. 4) Если вы хотите закрепить знания JS или пойти вглубь, то отлично подойдет курс из этой раздачи, а точнее "Бонус 1. Премиум курс по JavaScript (24 урока, 19,5 часов)" Курс будет полезен, даже если вы просто будете включать его например в метро. Но конечно лучше практики ничего нет 5) Более заумный сайт, который еще ближе к справке-документации. Обычно бывает полезным в более сложных вопросах, начинать с него я бы не советовал developer.mozilla.org Редактор кода Программировать можно хоть в стандартном блокноте от "виндоус", но я бы посоветовал выбрать что-нибудь посерьезнее. Но не слишком. Идеальным вариантом является "Sublime Text" . Он довольно быстрый, приятно выглядит, есть удобные горячие клавиши, которые заметно убыстряют написание кода. Потому объяснять буду именно на нем. Пишем свой первый скрипт Самое сложное в создании плагинов - начать. Легко повторить за учителем код в своем редакторе. Гораздо сложнее понять, почему он начал именно с этого и зачем делает то, без чего на твой взгляд можно обойтись. А главное - как вообще учитель понял, что надо изменить именно эту функцию, а не какую-то другую? За кучей текста про оформление плагина, указания автора и создании параметров легко можно потерять само программирование. Зачем нам учиться оформлять плагин, который мы еще не написали? Поэтому будем идти от важного к красивому. 1) Сначала будем осуществлять свои задумки, и только потом делать код лучше, а сам плагин презентабельней. 2) Сначала будем писать логику в мейкере, а потом уже переводить его в плагин. Так мы сможем понять, чем же код удобнее стандартных мейкерских средств. И так мы сможем разложить мейкер по кусочкам. 3) Я не буду говорить "берем и меняем эту стандартную функцию мейкера", а покажу, как нам понять, что менять надо именно ее. 4) Напишем тестовые сценарии для тестирования нашего скрипта Вызов общего события по нажатию кнопки ЦЕЛЬ: давайте представим, что нам надо вызвать общее событите при нажатии на определенную кнопку. ПРИМЕРЫ: 1) увеличить переменную на 1 2) показать переменную в сообщении 3) открытие картинки при нажатии на кнопку 4) использовать предмет для увеличения уровня здоровья героя 5) спрятать всё оружие при заходе в город 6) показать сообщение, в котором будем указано текущее время в игре, которое равно реальному времени игрока МЕЙКЕР: Для начала попробуем осуществить первые два пункта. На первый взгляд нет ничего проще сделать то же самое на ивентах: 1) создаем параллельное событие 2) пишем ветвление условий - "если кнопка "нас страницу вниз" нажата" (это кнопка W) 3) внутри него - "вызвать общее событие 1" 4) в самом общем событии пишем нужное нам действие, т.е. увеличение переменной 5) пишем ветвление условий - "если кнопка "нас страницу вверх" нажата" (это кнопка Q) 6) внутри него - "вызвать общее событие 2" 7) в самом общем событии пишем нужное нам действие, т.е. показ переменной в сообщении Проверка нажатия клавиш ТЕСТ: Сценарий 1: 1) Запускаем игру 2) нажимаем кнопку "W" для увеличении переменной 3) нажимаем кнопку "Q" для просмотра значения переменной Ожидаемый результат (то, что мы хотим увидеть. Далее - ОР): так как мы нажали один раз, то и переменная будет равной единице Фактический результат (то, что произошло при тесте. Далее - ФР): переменная больше единицы. В моем случае - пять. Значение переменной зависит от того, насколько долго мы держим клавишу. ЗАДАЧА: Как видим, в стандартной проверке нажатия клавиш учитывается нажатие на клавишу, а не ее отпускание. Мы конечно можем добавить паузу, как учит тот же небезызвестный Сириус, однако подобная реализация далека от идеала. Давайте попробуем исправить это программно и перевести события в код ПОИСК 1) Заходим в один очень полезный файлик, в котором содержатся команды для мейкера docs.google.com/spreadsheets/d/1-Oa0cRGp...etnvh7OHs/edit#gid=0 и ищем нужное нам 2) Если не знаем ЧТО исктаь остается гуглить ГУГЛЕЖ 1) Для того, чтоб понять как нам отследить нажатие клавиши в JS лезем в гугл и вбиваем что-нибудь типа "нажатие клавиши js" Переходим на уже знакомый нам сайт и видим learn.javascript.ru/keyboard-events Понимаем, что клавиши отслеживаются командами keyup, keydown, keypress. Лезем в гугл-переводчик, понимаем, что key - это клавиша. 2) Заходим в один очень полезный файлик, в котором содержатся команды для мейкера docs.google.com/spreadsheets/d/1-Oa0cRGp...etnvh7OHs/edit#gid=0 нажимаем CTRL+F для поиска и пытаемся найти сначала вышеназванный key. 3) на 186ой строке видим знакомые press, key 4) таким образом узнаем, что нажатие клавиш можно отследить через одну из команд, в скобках написав название клавиши (Input.isTriggered('ok'))
(Input.isRepeated('ok'))
(Input.isPressed('ok'))
(Input.isLongPressed('ok')) 6) На этот раз нам повезло. Именно isTriggered позволяет нам фиксировать нажатие кнопки как однократное СПРАВКА 1) Еще один способ, позволяющий найти нужное. Находясь в редакторе нажимаем F1 (это вызовет открытие справки мейкера). 2) Затем мотаем в самый низ в раздел JS Library и ищем КАК же может называться инициализация нажатия кнопок. В данном случае это Input. 2) Находим строчку isLongPressed, isTriggered и прочие и просто пробуем. Способ требует более глубоких знаний, так как информации много, а конкретных примеров в справке практически нет. Подключение всех клавиш клавиатуры Когда я впервые открыл МВ был очень разочарован, что клавиш стало еще меньше, чем в МВ. Впоследствии оказалось, что добавить их намного легче, чем кажется ЗАДАЧА: Итак, мы знаем, что команда (Input.isPressed('ok')) считывает нажатие клавиши. Теперь нам следует найти в коде движка ГДЕ же определяется название клавиш. Почему "ok" - это "ENTER"? ПОИСК 1) Тем, кто хоть немного нзает JS ясно, что isPressed('ok') - это метод объекта Input. А потому залазим в папку демки "js" и открываем по очереди каждый из файлов с разрешением ".js" 2) Нажимаем в редакторе кода клавиши CTRL+F, т.е. поиск, и вставляем туда "Input". Для быстрого перехода от одного найденного слова к другому нажимаем клавишу "F3" 3) После недолгих поисков видим довольно интересный кусок кода в rpg_core.js, а именно Input.keyMapper Как мы видим, в этом объекте (или ассоциативном массиве - кому как удобней) содержатся элементы в виде цифр и через двоеточие их значения типа "ok", "control". Давайте проверим, и вставим в ветвление условий что-нибудь из этого объекта, например 'control': Input.isTriggered('control') 4)Всё получилось, при нажатии клавиши "control", сообщение появляется. Более того, если мы и в ветвлении, и в объекте Input.keyMapper мы заменим слово control на любое другое, то всё опять же будет работать! Логика подсказывает, что цифры - это коды клавиш, а значение может быть таким, каким мы пожелаем. Добавляем другие клавиши клавиатуры 1) Давайте попробует найти коды остальных клавиш. Ввводим в гугле "клаивши js" и переходим по первой ссылке learn.javascript.ru/keyboard-events 2) Сайт оказывается довольно полезным. Ставим курсор туда, куда нас просят, а ниже мы видим код клавиши. В данном случае код клавиши 'b' то ли 98, то ли 66, а потому пробуем и то, и то 3) В редакторе ставим курсор на одну из строк внутри массива Input.keyMapper, жмем кнопку CTRL+SHIFT+D и строчка дублируется. Теперь вместо pageup пишем 'b', а вместо цифры подставляем по очереди 66 и 98 Как видим, 98 не рабоатет, а вот 66 в самый раз! Теперь вписываем код в событие и радуемся 4) Конечно, можно самому для каждой клавиши найти код. Но зачем изобретать велосипед? Вводим в гугле "все коды клаивши js", переходим по ссылке umi-cms.spb.su/ref/javascript/251/ и вуаля! Составляем громадный массив со всеми клавишами клавиатуры и вставляем его rpg_core.js . Перед массивом пишем комментарий, содержащий слово "тест", чтобы потом можно было быстро найти место, где ты что-то поправил ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] // список клавиш тест
Input.keyMapper = {
8: 'backspace', // backspace
9: 'tab', // tab
13: 'ok', // enter
16: 'shift', // shift
17: 'control', // control
18: 'alt', // alt
19: 'pause', // pause
20: 'capslock', // capslock
27: 'escape', // escape
32: 'space', // space
33: 'pageup', // pageup
34: 'pagedown', // pagedown
35: 'end', // end
36: 'home', // home
37: 'left', // left arrow
38: 'up', // up arrow
39: 'right', // right arrow
40: 'down', // down arrow
44: 'printscreen', // printscreen
45: 'insert', // insert
46: 'delete', // delete
48: '0', // 0
49: '1', // 1
50: '2', // 2
51: '3', // 3
52: '4', // 4
53: '5', // 5
54: '6', // 6
55: '7', // 7
56: '8', // 8
57: '9', // 9
65: 'a', // A ф
66: 'b', // B и
67: 'c', // C с
68: 'd', // D в
69: 'e', // E у
70: 'f', // F а
71: 'g', // G п
72: 'h', // H р
73: 'i', // I ш
74: 'j', // J о
75: 'k', // K л
76: 'l', // L д
77: 'm', // M ь
78: 'n', // N т
79: 'o', // O щ
80: 'p', // P з
81: 'q', // Q й
82: 'r', // R к
83: 's', // S ы
84: 't', // T е
85: 'u', // U г
86: 'v', // V м
87: 'w', // W ц
88: 'x', // X ч
89: 'y', // Y н
90: 'z', // Z я
96: 'escape', // numpad 0
97: 'numpad1', // numpad 1
98: 'down', // numpad 2
99: 'numpad3', // numpad 3
100: 'left', // numpad 4
101: 'numpad5', // numpad 5
102: 'right', // numpad 6
103: 'numpad7', // numpad 7
104: 'up', // numpad 8
105: 'numpad9', // numpad 9
106: '*', // *
107: '+', // +
109: '-', // -
110: '.', // .
111: '/', // /
112: 'f1', // F1
113: 'f2', // F2
114: 'f3', // F3
115: 'f4', // F4
116: 'f5', // F5
117: 'f6', // F6
118: 'f7', // F7
119: 'f8', // F8
120: 'debug', // F9
121: 'f10', // F10
122: 'f11', // F11
123: 'f12', // F12
144: 'numlock', // numlock
145: 'scrolllock', // scrolllock
186: ';', // :;ж
187: '=', // +=
188: '<', // <,Б
189: '-', // -_
190: '>', // >.Ю
191: '?', // /?,/.
192: '`', // ~`ё
219: '[', // {[х
220: '|', // |
221: ']', // }]ъ
222: '"' // "'э
} Вызов общего события скриптом ПОИСК 1) В нашем полезном файлике docs.google.com/spreadsheets/d/1-Oa0cRGp...etnvh7OHs/edit#gid=0 все команды рассортированы по командам в событии, поэтому мы довольно легко можем найти код, вызывающий общее событие $gameTemp.reserveCommonEvent(n); 2) Если же не выходит - вводим в переводчик слово "общее", выясняем, что на английском оно звучит как "Common", и после нажатия CTRL+F на вышеупомянутой страничке легко находим Common Event с вышеупомянутой командой КОДИМ 1) Логика подсказывает, что в $gameTemp.reserveCommonEvent(n) переменная n - это номер общего события. А значит, если мы введем $gameTemp.reserveCommonEvent(2), то вызовем второе общее событие. 2) Вставляем данный код в "скрипт" , сохраняем и проверяем. Всё работает! Делаем то же самое и для вызова первого события Замена ветвления событий кодом ПОИСК 1) Снова довольно легко находим в файлике docs.google.com/spreadsheets/d/1-Oa0cRGp...etnvh7OHs/edit#gid=0 строчку соответствия ветвления события - "Conditional Branch". Код в нем знакомый нам "if (code) { stuff } else { stuff }", т.е. обычные условия JS, где - if - если - code - условие. В данном случае это Input.isTriggered('b') и Input.isTriggered('control') - stuff - ЧТО будет при выполнении условия. В нашем случае $gameTemp.reserveCommonEvent(2) и $gameTemp.reserveCommonEvent(1) - else - "иначе". Пока нам не понадобится 2) Пишем то, что у нас получилось if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
} , а остальное удаляем. Проверяем и поздравляем себя! Параллельность кода Это всё конечно здорово, но на каждой карте постоянно вставлять это параллельное событие не есть хорошо. Поэтому давайте получившийся у нас код превратим в отдельный плагин КОДИМ 1) В папке js/plugine создаем файл например "input.js", где input - любое название, которое вы захотите 2) всталяем туда наш код if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
} ПОИСК 1) Часто в программировании практически во всех программах названия методов или функций одинаковые. К примеру: - "remove" или "delete" - удаления объектов - "add" - добавление - "is" - проверка есть ли у объекта определнное свойство, например isOpacity - "get" - считывание значения свойства объекта, например getHpActor вполне подошло бы для названия функции, возвращающей кол-во HP героя - "set" - запись значения свойства, например setHpActor подойдет для изменения здоровья героя Также и то, что в мейкере называют "параллельное событие" в программирование чаще всгео называют update. А поэтому давайте поищем что-то похожее и в коде мейкера 2) Разу уж нажатие клавиши находится в объекте Input в файле rpg_core.js, то адвайте поищем именно там. И практически сходу мы находим ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] Input.update = function() {
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
}; 3) Давайте скопируем всю эту функцию в наш плагин, и перед самым закрытием функции вставим наш код Input.update = function() {
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}; Назовем функцию triggeredKeys и вызовем ее в конце Input.update. this в данном случае равно Input Input.update = function() {
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
this.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
} 5) Если посмотреть на код, то становится понятно, что у нас дважды написана одна и та же функция "update". Input.update = function() {
//Input.update из rpg_core
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
//заканчивается функция апдейта
this.triggeredKeys();
}; 6) Зачем нам переписывать ее в свой плагин если мы можем скопировать ее в какую-нибудь переменную, а потом вызвать? Давайте так и сделаем. после тестов видим, что всё отлично работает! const updateCore = Input.update; //здесь мы сохраняем Input.update из rpg_core в константу updateCore
Input.update = function() {
updateCore.call(this); //вызываем функцию updateCore
this.triggeredKeys(); //вызываем нашу функцию triggeredKeys.
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
} Защищаем наши функции Часто в плагинах можно встретить конструкцию (function(){}) () . Как говорят, это "самовызывающаяся функция для защиты переменных". Этот шаблон часто используется при попытке избежать загрязнения глобального пространства имен, поскольку все переменные, используемые внутри IIFE (как и в любой другой нормальной функции), не видны за пределами его объема. Конечно, можно его вставить и забыть, не разобравшись, но давайте все-таки разберемся. КОДИМ 1) Давайте попробуем защитить наши переменные. Что надо сделать, чтоб переменные в нашей функции перестали быть глобальными? Конечно же,обернуть код в функцию, допустим назовем ее "a" const a = function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
}; 2) Теперь наш плагин сломан. Наш "апдейт" не обновляется, ведь теперь он в функции. А потому вызываем нашу функцию в конце плагина const a = function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
};
a(); //вызов функции 3) Можем написать более кратко - сразу после функции написать круглые скобки для мгновенного вызова const a = function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
}(); //вызов функции 4) Теперь ясно, что переменная "а" нам не нужна. Зачем она, если затем ее совсем не используем. Избалвяемся от нее и снова у нас ничего не рбаотает function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
}(); //вызов функции 5) Так как JS после слова function хочет видеть ее название, а его нет, то и наш код ошибочный. Что делать? Как заставить JS распознать наш функцию как анонимную, т.е. без названия? Для этого вспомним ГДЕ мы используем анонимные функции. Например, при передаче функции как аргумент в другую функцию присваивать функцию перемнной не требуется func(function () {}, 2) Поэтому давайте попробует обитрить и заключить нашу функцию в скобки (function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
})(); И о чудо, JS увидело скобку, поняла, что сейчас будет следовать выражение, а не функция, а раз это выражение, то и анонимную функцию использовать в ней можно 6) Кроме скобок подойдет любой символ, который бы показывал JS что перед нами выражение. Например унрарные плюсы или минусы -function () {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
}
}(); 7) Кроме того, как и любой функции мы можем передать ей аргумент +function (numb) {
const updateCore = Input.update;
Input.update = function() {
updateCore.call(this);
Input.triggeredKeys();
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
console.log(numb);
$gameTemp.reserveCommonEvent(2)
}
}
}(2); ИТОГО: Итого мы получили маленький плагинчик. Но цель урока была не конкретно в написании плагина, а в умении находить чать кода, которая нужна именно для нашего случая. ДОМАШНЕЕ ЗАДАНИЕ Надеюсь, что после данной статейки любой сможет написать плагин не только для вызова общих событий нажатия на клавишу, но и конкретные действия при нажатиях без использования общих событий. 1) увеличить переменную на 1 2) показать переменную в сообщении 3) открытие картинки при нажатии на кнопку 4) использовать предмет для увеличения уровня здоровья героя 5) спрятать всё оружие при заходе в город 6) показать сообщение, в котором будем указано текущее время в игре, которое равно реальному времени игрока Ответы в любом случае будут, а вот буду ли дальше писать зависит от отзывов, все-таки времени уходит много, а его ужас как не хватает |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 6 года 2 дн. назад #107217
|
yuryol пишет:
Зачем нам переписывать ее в свой плагин если мы можем скопировать ее в какую-нибудь переменную, а потом вызвать? Давайте так и сделаем. после тестов видим, что всё отлично работает! const updateCore = Input.update; //здесь мы сохраняем Input.update из rpg_core в константу updateCore
Input.update = function() {
updateCore.call(this); //вызываем функцию updateCore
this.triggeredKeys(); //вызываем нашу функцию triggeredKeys.
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
} Я правильно понимаю, что если используется несколько плагинов, переписывающих Input.update, то такой способ перепеси позволит им не конфликтовать? А конфликтовать будет при: Input.update = function() {
//Input.update из rpg_core
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
//заканчивается функция апдейта
this.triggeredKeys();
}; |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 6 года 1 день назад #107222
|
Noxmils пишет:
yuryol пишет: Зачем нам переписывать ее в свой плагин если мы можем скопировать ее в какую-нибудь переменную, а потом вызвать? Давайте так и сделаем. после тестов видим, что всё отлично работает! const updateCore = Input.update; //здесь мы сохраняем Input.update из rpg_core в константу updateCore
Input.update = function() {
updateCore.call(this); //вызываем функцию updateCore
this.triggeredKeys(); //вызываем нашу функцию triggeredKeys.
};
Input.triggeredKeys = function() {
if (Input.isTriggered('b')) {
$gameTemp.reserveCommonEvent(1)
}
if (Input.isTriggered('control')) {
$gameTemp.reserveCommonEvent(2)
}
} Я правильно понимаю, что если используется несколько плагинов, переписывающих Input.update, то такой способ перепеси позволит им не конфликтовать? А конфликтовать будет при: Input.update = function() {
//Input.update из rpg_core
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
this._updateDirection();
//заканчивается функция апдейта
this.triggeredKeys();
}; грубо говоря да. Во первом случае мы сохраняем первоначальную функцию а потом вызываем ее в нашей функции. Во втором случае мы изменяем первоначальную функцию, из-за чего чужой плагин при обращении к первоначальной функции будет натыкаться на нашу и в первую очередь от тебя жду домашнее задание |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 6 года 1 день назад #107234
|
Ну, отчасти я д/з выполнил . В частности, пункты 1 и 2. Отчасти выполнил пункт 4, только вместо увеличения здоровья накладывается состояние.
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] //=============================================================================
// Alcoholism
//=============================================================================
/*:
*@plugindesc Считает количество выпитых бутылок водки и накладывает с некоторой вероятнгостью состояние алкоголизма при определенном количестве выпитого
*@author Noxmils
*@help Сбацано в качестве домашего задания к уроку от yuriol
*
*@param VodkaID
*@desc ИД итема "Бутылка водки"
*@default 1
*@type item
*
*@param Drunk
*@desc Выпито бутылок
*@default 1
*@type variable
*
*@param AlcoholismID
*@desc ИД состояния алкоголизма
*@default 1
*@type state
*
*@param Easy_Drunk
*@desc Количество бутылок водки, которое можно выпить до появления вероятности стать алкашом
*@default 5
*@type number
*
*/
(function () {
var VodkaID = PluginManager.parameters('Alcoholism')['VodkaID'];
var Drunk = PluginManager.parameters('Alcoholism')['Drunk'];
var AlcoholismID = PluginManager.parameters('Alcoholism')['AlcoholismID'];
var Easy_Drunk = PluginManager.parameters('Alcoholism')['Easy_Drunk']
Input.keyMapper = {
9: 'tab', // tab
13: 'ok', // enter
16: 'shift', // shift
17: 'control', // control
18: 'control', // alt
27: 'escape', // escape
32: 'ok', // space
33: 'pageup', // pageup
34: 'pagedown', // pagedown
37: 'left', // left arrow
38: 'up', // up arrow
39: 'right', // right arrow
40: 'down', // down arrow
45: 'escape', // insert
68: 'drink', // D
81: 'pageup', // Q
87: 'pagedown', // W
88: 'escape', // X
90: 'ok', // Z
96: 'escape', // numpad 0
98: 'down', // numpad 2
100: 'left', // numpad 4
102: 'right', // numpad 6
104: 'up', // numpad 8
120: 'debug' // F9
};
const PressUpdate = Input.update;
Input.update = function () {
PressUpdate.call(this);
this.wantDrink();
}
Input.wantDrink = function () {
if (Input.isTriggered('drink') && !$gameMessage.isBusy()){
this.DrinkEffect();
}
}
Input.DrinkEffect = function () {
this.LetsDrink();
if ((Easy_Drunk < $gameVariables.value(Drunk)) && (!$gameParty.leader().isStateAffected(AlcoholismID))) {
let fortuna = Math.random();
if (fortuna < 0,5) {
$gameParty.leader().addState(AlcoholismID);
$gameMessage.setFaceImage('Actor1',0);
$gameMessage.setBackground(1);
$gameMessage.setPositionType(1);
$gameMessage.add('Now you are ALKASH!');
};
};
}
Input.LetsDrink = function () {
if ($gameParty.hasItem($dataItems[VodkaID])) {
$gameParty.loseItem($dataItems[VodkaID], 1);
$gameVariables.setValue(Drunk, $gameVariables.value(Drunk) + 1);
this.HaveVodkaMessage();
} else {
this.WithoutVodkaMessage();
};
}
Input.HaveVodkaMessage = function () {
if ($gameParty.leader().isStateAffected(AlcoholismID)) {
$gameMessage.setFaceImage('Actor1',0);
$gameMessage.setBackground(1);
$gameMessage.setPositionType(2);
$gameMessage.add('Хорошо пошла!');
} else {
$gameMessage.setFaceImage('Actor1',0);
$gameMessage.setBackground(1);
$gameMessage.setPositionType(2);
$gameMessage.add('Хо-хо! Выпил уже ' + $gameVariables.value(Drunk) + ' и не спился');
};
}
Input.WithoutVodkaMessage = function () {
if ($gameParty.leader().isStateAffected(AlcoholismID)) {
$gameMessage.setFaceImage('Actor1',0);
$gameMessage.setBackground(1);
$gameMessage.setPositionType(2);
$gameMessage.add('Блэт! Надо похмелиться!');
} else {
$gameMessage.setFaceImage('Actor1',0);
$gameMessage.setBackground(1);
$gameMessage.setPositionType(2);
$gameMessage.add('Я выпил всего лишь ' + $gameVariables.value(Drunk) + '! Можно еще выпить.');
};
}
})() |
Последнее редактирование: 6 года 1 день назад от Noxmils. Причина: Заменил "пункт 3" на "пункт 4"
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 6 года 1 день назад #107235
|
Пара нюансов всплыла по ходу выполнения д/з. Первое, ты сделал свою функцию методом Input. Объясни, зачем это нужно. Даже если этот нюанс должен знать любой джавер скриптер, пояснить было бы не плохо и, желательно, таким же простым языком, как и весь урок. Второе, нет ли менее конфликтного способа добавлять активные кнопки, чем напрямую вписывать их в Input.keyMapper? Я пробовал Input.keyMapper.68, но что-то не пошло
|
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: yuryol
|
Покодим (уроки программирования для RPG maker MV) 6 года 22 ч. назад #107237
|
Сразу отмечу, что плагин YEP (Yanfly) – Keyboard Config ломает практически все плагины, которые меняют настройки клавиатуры, потому что он переопределяет Input.keyMapper по ходу игры!
|
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 6 года 19 ч. назад #107238
|
Noxmils пишет:
Пара нюансов всплыла по ходу выполнения д/з. Первое, ты сделал свою функцию методом Input. Объясни, зачем это нужно. Даже если этот нюанс должен знать любой джавер скриптер, пояснить было бы не плохо и, желательно, таким же простым языком, как и весь урок. Второе, нет ли менее конфликтного способа добавлять активные кнопки, чем напрямую вписывать их в Input.keyMapper? Я пробовал Input.keyMapper.68, но что-то не пошло спасибо за комменты! устаю на работе жесть, поэтому пока на одно предложение отвечу: надо писать Input.keyMapper[68], а не Input.keyMapper.68. Так как в случаях если имя свойства объекта (или имя элемента массива) строка, начинается с цифры или содержит в себе пробелы, то надо использовать квадратные скобки а не точку. |
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Noxmils
|
Покодим (уроки программирования для RPG maker MV) 5 года 11 мес. назад #107257
|
В качестве д/з я решил написать что-то, что будет использовано в проекте. Но я решил пойти немного дальше показанного в уроке и самостоятельно разобрался с удерживанием кнопки
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] //=============================================================================
// LookAtMap v0.1
//=============================================================================
/*:
*@plugindesc При нажатой клавише М показывает карту, если игрок на глобальной карте
*@author Noxmils
*@help Данная версия создана в качестве домашего задания к уроку от yuriol
*
*@param WorldMaps
*@desc ИД карт мира
*@type number[]
*
*@param BackgroundPicture
*@desc Название файла с задним фоном для карты
*@default Paper
*@type text
*
*@param BackgroundX
*desc Положение заднего фона для карты по оси Х
*@default 48
*@type number
*
*@param BackgroundY
*@desc Положение заднего фона для карты по оси У
*@default 48
@type number
*
*@param MapPictures
*@desc название изображений карт
*@type text[]
*
*@param Place_X
*@desc Положение карт по оси Х
*@type number[]
*
*@param Place_Y
*@desc Положение карт по оси У
*@type number[]
*
*@param MapWidth
*@desc Ширина карт
*@type number[]
*
*@param MapHeight
*@desc Высота карт
*@type number[]
*
*@param PlayerMarker
*@desc Название файла с иконкой маркера игрока
*@default Marker
*@type text
*
*/
(function () {
var WorldMaps = PluginManager.parameters('LookAtMap')['WorldMaps'];
var Background = PluginManager.parameters('LookAtMap')['BackgroundPicture'];
var BackgroundX = PluginManager.parameters('LookAtMap')['BackgroundX'];
var BackgroundY = PluginManager.parameters('LookAtMap')['BackgroundY'];
var MapPictures = PluginManager.parameters('LookAtMap')['MapPictures'];
var Place_X = PluginManager.parameters('LookAtMap')['Place_X'];
var Place_Y = PluginManager.parameters('LookAtMap')['Place_Y'];
var MapWidth = PluginManager.parameters('LookAtMap')['MapWidth'];
var MapHeight = PluginManager.parameters('LookAtMap')['MapHeight'];
var PlayerMarker = PluginManager.parameters('LookAtMap')['PlayerMarker'];
Input.keyMapper[77] = 'Map'; // M
var MapActive = false;
const PressUpdate = Scene_Map.prototype.update;
Scene_Map.prototype.update = function () {
PressUpdate.call(this);
this.PressMap();
}
Scene_Map.prototype.PressMap = function () {
if (Input.isPressed('Map') && !$gameMessage.isBusy()){
this.TryToLook();
} else if (MapActive && this.SelectMap() != undefined) {
for (var j = 1; j < 100; j++) {
$gameScreen.erasePicture(j);
};
MapActive = false;
} else if (MapActive && this.SelectMap() == undefined){
$gameMessage.clear();
MapActive = false;
}
}
Scene_Map.prototype.TryToLook = function () {
if (this.SelectMap() != undefined) {
MapActive = true;
$gameScreen.showPicture(1, Background, 0, BackgroundX, BackgroundY, 100, 100, 255, 0)
this.ShowMap();
this.ShowPosition();
} else {
this._mapNameWindow.open();
}
}
Scene_Map.prototype.SelectMap = function () {
var WorldMapsArr = eval(WorldMaps);
for (let i = 0; i < WorldMaps.length; i++) {
if ( WorldMapsArr[i] == $gameMap.mapId()) {
return i;
}
};
return undefined;
}
Scene_Map.prototype.ShowMap = function () {
var MapPicturesArr = eval(MapPictures);
var Place_X_Arr = eval(Place_X);
var Place_Y_Arr = eval(Place_Y);
$gameScreen.showPicture(2, MapPicturesArr[this.SelectMap()], 0, Place_X_Arr[this.SelectMap()], Place_Y_Arr[this.SelectMap()], 100, 100, 255, 0);
}
Scene_Map.prototype.ShowPosition = function () {
var MapWidthArr = eval(MapWidth);
var MapHeightArr = eval(MapHeight);
var Place_X_Arr = eval(Place_X);
var Place_Y_Arr = eval(Place_Y);
let PosX = +Place_X_Arr[this.SelectMap()] + ($gamePlayer.x + 0.5) * MapWidthArr[this.SelectMap()] / $gameMap.width();
let PosY = +Place_Y_Arr[this.SelectMap()] + ($gamePlayer.y + 0.5) * MapHeightArr[this.SelectMap()]/ $gameMap.height();
$gameScreen.erasePicture(3);
$gameScreen.showPicture(3, PlayerMarker, 1, PosX, PosY, 100, 100, 255, 0);
}
})() Вот так выглядит карта при удерживании клавиши М Благодаря уроку я наконец-то научился структурировать код, а то раньше все пихал в одну функцию. Также, наверно, научился верно находить требуемые функции в стандартных плагинах (функцию вставки имени карты нашел за несколько секунд, раньше искал бы весь день). И еще, теперь мне открылась истинная мощь кнопки для команды скрипта. Раньше я ею только функции в js файлах через событие вызывал... Эх, знал бы раньше Само собой, теперь я стал мочь добавлять новые активные клавиши. Спасибо, Юриол, за отличный урок! Надеюсь ты и дальше будешь так же доступно просвещать всех, кто хочет научиться немного плагинить. |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 11 мес. назад #107306
|
получилось! убила три часа
сделала появление картинки при нажатии на клавишу и исчезновение на другую )) можно ли как-то сделать появление и исчезновение на одну и ту же клавишу? пыталась сделать через $gameSwitches.setValue(1, 'true') , не поняла как. Если показываем картинку, то добавляем строчку $gameSwitches.setValue(1, 'true') . Если выключаем то $gameSwitches.setValue(1, 'false') ? нажимала F8 - переключатель как был выключен,так и остался. через переменную тоже не вышло. пробовала через $gameVariables.setValue(1, 1) приравнивать переменную к 1 если картинка открыта и к 0 если закрыли. тут уже получилось,переменная меняется. но как потом в плагине проверить чем равна переменная? пробовала $gameVariables.setValue(1, value) == 0, но ошибка не ругайте если вопросы глупые (( |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 11 мес. назад #107307
|
Noxmils пишет:
Благодаря уроку я наконец-то научился структурировать код, а то раньше все пихал в одну функцию. Также, наверно, научился верно находить требуемые функции в стандартных плагинах (функцию вставки имени карты нашел за несколько секунд, раньше искал бы весь день). И еще, теперь мне открылась истинная мощь кнопки для команды скрипта. Раньше я ею только функции в js файлах через событие вызывал... Эх, знал бы раньше Само собой, теперь я стал мочь добавлять новые активные клавиши. Спасибо, Юриол, за отличный урок! Надеюсь ты и дальше будешь так же доступно просвещать всех, кто хочет научиться немного плагинить. и тебе спасибо,мой лучший ученик! время опять забито, посмотреть пока не могу, но как найду так сразу =З Iri пишет: получилось! убила три часа сделала появление картинки при нажатии на клавишу и исчезновение на другую )) можно ли как-то сделать появление и исчезновение на одну и ту же клавишу? пыталась сделать через $gameSwitches.setValue(1, 'true') , не поняла как. Если показываем картинку, то добавляем строчку $gameSwitches.setValue(1, 'true') . Если выключаем то $gameSwitches.setValue(1, 'false') ? нажимала F8 - переключатель как был выключен,так и остался. через переменную тоже не вышло. пробовала через $gameVariables.setValue(1, 1) приравнивать переменную к 1 если картинка открыта и к 0 если закрыли. тут уже получилось,переменная меняется. но как потом в плагине проверить чем равна переменная? пробовала $gameVariables.setValue(1, value) == 0, но ошибка не ругайте если вопросы глупые (( к сожаленью тоже пока не могу помочь. сразу вижу,что true и false в кавычках. скорее всего надо без них ну и видимо скрипты ты находила здесь - тык в третьем столбце напротив $gameVariables.setValue(1, value) нужные тебе проверки для переключателей: ($gameSwitches.value(1) == true) && ($gameSwitches.value(2) == true) && ($gameSwitches.value(3) == true) $gameVariables.value(1) == 1 |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 11 мес. назад #107308
|
Iri, мне кажется, что для плагина лучше создать отдельную переменную, а не пользоваться мейкерскими. Это позволит снизить вероятность перепутать переменные в ходе создания проекта.
var pictureShow = false
if (Input.isTriggered('тут могла быть Ваша кнопка') && pictureShow == false) {
//здесь код вставки картинки
pictureShow = true;
} else if (Input.isTriggered('тут могла быть Ваша кнопка') && pictureShow == true) {
//Здесь код удаления картинки
pictureShow = false;
} Первый иф сработает, если нажата книпка И переменная-переключатель выключена (что должно соответствовать отсутствию данной картинки на экране). В этом случае картинка выводится на экран, а переменная-переключатель переводится в состояние ВКЛ (true). Элс иф сработает в случае, если кнопка нажата И переменная-переключатель включена (т.е. картинка на экране). Тогда картинка эта картинка удаляется, а переменная выключается (становится false) |
Последнее редактирование: 5 года 11 мес. назад от Noxmils.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: NeKotZima
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108183
|
Очень интересная тема, жалко что заглохла. Интересно наблюдать, как код преобразуется из "новичковского" до хорошего.
Надеюсь, что код Noxmilsа все-таки проревьюят У меня вопрос по поводу Input.keyMapper. Как добавить ОДНУ клавишу? Пробовал и Input.keyMapper[68]="action", и другие ухищрения, но несмотря на то, что в консольке показано, что объект изменился, все-равно при нажатии на кнопку Input.isTriggered('action') ничего не происходит. |
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108186
|
NeKotZima пишет:
У меня вопрос по поводу Input.keyMapper. Как добавить ОДНУ клавишу? Пробовал и Input.keyMapper[68]="action", и другие ухищрения, но несмотря на то, что в консольке показано, что объект изменился, все-равно при нажатии на кнопку Input.isTriggered('action') ничего не происходит. У меня работает. Я создал плагин с кодом:Input.keyMapper[68]="action"; Потом я создал параллельное событие с ветвлением условий, постоянно в фоновом режиме проверяющее истинность скрипта Input.isTriggered('action') и что-то делающее, если клавиша нажата: Если что, вот как настраивается Ветвление условий [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] И у меня оно работает — при нажатии на клавишу D (68 — это код клавиши D) выводится сообщение: Если у вас не работает, возможно, проблема в конфликте с каким-то другим плагином? Вроде бы DK говорил, что некоторые плагины Yanfly целиком переписывают Input.keyMapper. Стоит попробовать отключать плагины один за одним и проверять, изменится ли что-то — так можно узнать, из-за какого плагина происходит конфликт. |
Последнее редактирование: 5 года 10 мес. назад от Dmy.
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108214
|
NeKotZima пишет:
Очень интересная тема, жалко что заглохла. Интересно наблюдать, как код преобразуется из "новичковского" до хорошего. спасибо!Надеюсь, что код Noxmilsа все-таки проревьюят У меня вопрос по поводу Input.keyMapper. Как добавить ОДНУ клавишу? Пробовал и Input.keyMapper[68]="action", и другие ухищрения, но несмотря на то, что в консольке показано, что объект изменился, все-равно при нажатии на кнопку Input.isTriggered('action') ничего не происходит. на счет кода тоже всё работает, возможно проблема при вызове или конфликты с другими плагинами как сказала Dmy Noxmils пишет: В качестве д/з я решил написать что-то, что будет использовано в проекте. Но я решил пойти немного дальше показанного в уроке и самостоятельно разобрался с удерживанием кнопки пока чисто по коду, сам плагин не вставлял в мукер, возможно где-то я не прав1) в нескольких местах вижу у тебя сравнения типа (this.SelectMap() != undefined). не обязательно писать "!= undefined", попробуй просто (this.SelectMap()) Точно также (pictureShow == false) можно исправить на (!pictureShow), а (pictureShow == true) на (!pictureShow) часто рекомендуют оставлять сравнения для читаемости,но по мне так сейчас практически все сходу понимают подобные записи,даже новички,поэтмоу читаемость не пострадает похожая ситуация с "return undefined;" . можешь просто написать return; опять же если хочешь обязательно возвратить что-то, то лучше возвращать например null или false, так как по своей сути undefined - это отсутствие значения. грубо говоря обработчик нам говорит что мы проглядели и не присвоили переменой ничего. в данном же случае мы намеренно возвращаем "ничего", а потому лучше исползовать null или false 2) при объявлении переменных для параметров вижу у тебя повторяющуюся конструкцию PluginManager.parameters('LookAtMap') получается дублирование кода плюс если именишь название то придется всё заменять в разных местах. поэтому от нее лучше избавиться,объявив перед переменными переменную const parameters = PluginManager.parameters('LookAtMap'), а затем уже var WorldMaps = parameters; и остальные 3) не очень понял зачем ты использвоал eval. 4) названия переменных лучше давать одинакового типа. у тебя тут и верблюжий стиль, и змеинный. в большинстве у тебя верблюжий, поэтому вместо Place_X_Arr лучше назови PlaceXArr. ну и локальные переменные я бы обзывал покороче, тем более в функции из четырех строк также если несколько переменных подряд можно не писать var, а убрать их,а точки с запятыми заменить на запятые. итого я бы переписал функцию например вместо var MapPicturesArr = eval(MapPictures);
var Place_X_Arr = eval(Place_X);
var Place_Y_Arr = eval(Place_Y);
$gameScreen.showPicture(2, MapPicturesArr[this.SelectMap()], 0, Place_X_Arr[this.SelectMap()], Place_Y_Arr[this.SelectMap()], 100, 100, 255, 0); var pictures = eval(MapPictures),
map = this.SelectMap(),
x = eval(Place_X),
y = eval(Place_Y);
$gameScreen.showPicture(2, pictures[map], 0, x[map], y[map], 100, 100, 255, 0); по мне так читается намного проще 5) большая вложенность не есть хорошо, поэтому: - избавляемся от "else if", - у if и for избавляемся от скобочек если внутри них всего короткая строка Scene_Map.prototype.PressMap = function () {
if (Input.isPressed('Map') && !$gameMessage.isBusy()){
this.TryToLook();
} else if (MapActive && this.SelectMap() != undefined) {
for (var j = 1; j < 100; j++) {
$gameScreen.erasePicture(j);
};
MapActive = false;
} else if (MapActive && this.SelectMap() == undefined){
$gameMessage.clear();
MapActive = false;
}
} имхо лучше так Scene_Map.prototype.PressMap = function () {
if (Input.isPressed('Map') && !$gameMessage.isBusy()) this.TryToLook();
if (MapActive && this.SelectMap()) {
for (var j = 1; j < 100; j++) $gameScreen.erasePicture(j);
MapActive = false;
}
if (MapActive && !this.SelectMap()){
$gameMessage.clear();
MapActive = false;
}
} или так Scene_Map.prototype.PressMap = function () {
if (Input.isPressed('Map') && !$gameMessage.isBusy()) this.TryToLook();
if (!MapActive) return;
if (this.SelectMap()) {
for (var j = 1; j < 100; j++) $gameScreen.erasePicture(j);
} else {
$gameMessage.clear();
}
MapActive = false;
} 6) не уверен что ничего не поломаю но скорее всего эту функцию Scene_Map.prototype.TryToLook = function () {
if (this.SelectMap() != undefined) {
MapActive = true;
$gameScreen.showPicture(1, Background, 0, BackgroundX, BackgroundY, 100, 100, 255, 0)
this.ShowMap();
this.ShowPosition();
} else {
this._mapNameWindow.open();
}
} можно переписать на Scene_Map.prototype.TryToLook = function () {
if (!this.SelectMap()) return this._mapNameWindow.open();
MapActive = true;
$gameScreen.showPicture(1, Background, 0, BackgroundX, BackgroundY, 100, 100, 255, 0)
this.ShowMap();
this.ShowPosition();
} я бы оставил твой вариант, но просто чтоб знал что можно и так. 7) опять же не уверен, возможно эту функцию Scene_Map.prototype.SelectMap = function () {
var WorldMapsArr = eval(WorldMaps);
for (let i = 0; i < WorldMaps.length; i++) {
if ( WorldMapsArr[i] == $gameMap.mapId()) {
return i;
}
};
return undefined;
} можно переписать на Scene_Map.prototype.SelectMap = function () {
var WorldMapsArr = eval(WorldMaps);
for (let i = 0; i < WorldMaps.length; i++)
return ( WorldMapsArr[i] == $gameMap.mapId() ) ? i : null;
} Ждем от тебя новых плагинов! |
Последнее редактирование: 5 года 10 мес. назад от yuryol.
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108220
|
yuryol пишет:
1) в нескольких местах вижу у тебя сравнения типа (this.SelectMap() != undefined). не обязательно писать "!= undefined", попробуй просто (this.SelectMap()) Точно также (pictureShow == false) можно исправить на (!pictureShow), а (pictureShow == true) на (!pictureShow) часто рекомендуют оставлять сравнения для читаемости,но по мне так сейчас практически все сходу понимают подобные записи,даже новички,поэтмоу читаемость не пострадает 1) Ну вот ты сам перечитай, что ты написал... (pictureShow == true) на (!pictureShow) Сравнения оставляют не только, чтобы читаемость была лучше, но и для избежания таких вот ошибок, это раз. Во-вторых, сравнения оставляют, чтобы оптимизировать код (для этого надо использовать сравнения с ===), потому что в таком случае процессор не будет пытаться привести выражение к булевому типу. Пример: var a = undefined; if (a === undefined) if (!a) Первый вариант будет работать чуточку быстрее, потому что во втором случае придется приводить "a" к булевому типу, а потом делать отрицание. 2) похожая ситуация с "return undefined;" . можешь просто написать return; Лучше оставить return undefined; 3) в данном же случае мы намеренно возвращаем "ничего", а потому лучше исползовать null или false Если уж мы возвращаем "ничего", то только null. false использовать, если функция возвращает логическое значение. 7) нельзя. В твоем варианте значение вернется при первой же итерации. |
Последнее редактирование: 5 года 10 мес. назад от DK.
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108221
|
Ого. У вас тут комментирование чужих скриптов уже не считается притеснением автора и попыткой его обидеть? Круто
Но писать много нет настроения. Поэтому только один самый поверхностный вопрос: Почему функция действия selectMap() возвращает не успех/провал (aka Bool), а какой-то другой тип? Не лучше тогда назвать функцию в духе "indexOfVisibleWorldMap"? |
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Noxmils
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108222
|
DK пишет:
... 1) ну тут опечатка, все-таки литрик крепкого пива выпил =З трезвым в таком ошибиться не труднее чем с !== и === про то что быстрее не задумывался,пасибо. пойду переписывать абс 2) а тут почему "Лучше оставить return undefined"? только для читаемости? опять же лучше null же? 3) ну "false" я привел для примера, типа какие есть варианты избежать андефайнд. 7) точно. тогда я бы просто от фигурных избавился =З Scene_Map.prototype.SelectMap = function () {
var WorldMapsArr = eval(WorldMaps);
for (let i = 0; i < WorldMaps.length; i++) {
if ( WorldMapsArr[i] == $gameMap.mapId()) return i;
};
return undefined;
} Ого. У вас тут комментирование чужих скриптов уже не считается притеснением автора и попыткой его обидеть? Круто в скриптах не место для неженок |
Последнее редактирование: 5 года 10 мес. назад от yuryol.
Администратор запретил публиковать записи гостям.
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108223
|
2) Да. Можно и null.
7) Раньше я тоже писал все возможные условия в одну строчку, но потом понял, что красивее выглядит, когда действие переносится на следующую строчку. И читаемость лучше. |
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Noxmils
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108224
|
Ага. Только есть еще момент с кучей if'ов идущих подряд и не выходит сделать иначе. Там единственное действие на той же строке выглядит удобно.
|
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Noxmils
|
Покодим (уроки программирования для RPG maker MV) 5 года 10 мес. назад #108226
|
Ответ на первое сообщение Юриола.
1) Я делал this.SelectMap() != undefined из-за того, что есть возможность, что оно будет равно 0. Насколько я знаю, 0 в условии - это то же самое, что false. 2) Такой кодинг - пережиток моей специальности. У нас тут наоборот, стремятся сократить количество переменных в ущерб длине уравнения. У меня эта идея постоянно вылезает при написании кода. 3) На тот момент я не знал о JSON.parse . Дмай и ДК меня в чате потом просветили) 4) Я писал Place_X_Arr по субъективным соображениям. Без нижних пробелов я легко путаю PlaceXArr и PlaceYArr. Про написание переменных через запятую... я не знал, что так можно . Теперь я понимаю, что мне постоянно предлагал Brackets. 5) Один из else if должен срабатывать ТОЛЬКО при ложности первого условия. При верном первом условии, у одного else if условие также верно. Как следствие, по твоему примеру будет срабатывать два условия. 6) Запомню этот прием! 7) Да, у тебя лучше. Я забыл об операторе ?, а если бы и помнил, то побоялся совать все это в return P.S. Посмотрел твой диалог с ДК. По поводу переноса return i на ту же строку что и if: мне такое тоже кажется удобным, но я так не делал, т.к. думал, что так делать не принято, вот и плодил строки. |
Последнее редактирование: 5 года 10 мес. назад от Noxmils.
Администратор запретил публиковать записи гостям.
|
|
Время создания страницы: 0.599 секунд