Помните я обещал научиться делать плагины для MV? Мейкерист сказал - мейкерист сделал! Поскольку делать маленькие штуки не в моём стиле, я написал целый небольшой сервис и назвал его
- Название работы: BugReporter
- Имя автора работы: ZX_Lost_Soul
- Для какого редактора написана работа: RPG Maker MV (проверено на версиях 1.2.0, 1.5.1)
- Контактная информация (как связаться): через личные сообщения на этом форуме
- Как узнали о нашем кокурсе: от покемона Катерпи
Я долго думал какой плагин может быть полезен Светлому сообществу. На Светлой люди довольно часто выкладывают проекты в разработке, демо-версии и получают отзывы от игроков. Однако, иногда бывает очень муторно скринить в игре каждый косяк, сворачивать игру для добавления заметок и потом вставлять скрины в сообщение. К тому же, иногда скриншота недостаточно, чтобы разобраться в проблеме, нужны и игровые данные. Этот плагин призван решить эту задачу!
Что же он делает:
Если во время игры нажать
Page Down - игра приостановится и откроется окно, в котором игрок сможет оставить комментарий по ситуации (или оставить пустым). Выглядит это так:
После нажатия
Отправить или же повторного
Page Down скриншот отправится на страничку игры:
ССЫЛКА
Как видите, к скриншотам прилагается не только
имя автора и
комментарий, но и
состояния игровых переменных.
Если плагин вам придётся по душе, в будущем возможно расширение функционала по вашему желанию
Очень надеюсь что вам он понравится и будет использован в каких-нибудь играх
Небольшой бонус: на страничке каждого скриншота имеется код, который можно скопировать, чтобы легко вставить скриншот на форум Светлой зоны или другой сайт!
Ссылка на скачивание:
BugReporter.js
Код плагина:
/*
* The MIT License
*
* Copyright (c) 2017 ZX_Lost_Soul
*
* Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, слияние, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, а также лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
*
* Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.
*
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, В ТОМ ЧИСЛЕ, ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
*/
//=============================================================================
// BugReporter.js
//=============================================================================
/*:
* @plugindesc Данный плагин поможет Вашим игрокам легко и быстро сообщить Вам о багах, недоработках игры или просто оставить какие-либо пожелания!
* @author ZX_Lost_Soul
* @help Версия плагина: 1.0
Если во время игры нажать "Page Down" - игра приостановится и откроется окно,
в котором игрок сможет оставить комментарий по ситуации (или оставить пустым).
После повторного нажатия "Page Down" окно закроется и на сайт bugreporter.4ky.ru
будет отправлен скриншот игры, введённое описание, а также состояния игровых
переменных (для удобства выявляения проблемы автором игры).
Всё, что нужно, чтобы использовать плагин - создать страничку игры на
bugreporter.4ky.ru и скопировать оттуда ключ API в соответствующую настройку
плагина (справа).
Плагин создан специально для сайта "Светлая зона и Академия RPG Maker",
заходите к нам на rpgmaker.ru :)
*
* @param Ключ API (обязательно)
* @desc Ключ API для вашей игры. Создайте страничку игры на bugreporter.4ky.ru, чтобы получить ключ.
*
* @param Горячая клавиша
* @desc Код клавиши для открытия окна отправки. По-умолчанию это клавиша "Page Down". Узнать коды можно на keycode.info
* @default 34
* @param Отправлять переменные?
* @desc Приложить к скриншоту данные о состоянии переменных и переключателей? (да/нет)
* @default да
*/
(function() {
var parameters = PluginManager.parameters('BugReporter'); // Получаем параметры плагина
var apiKey = String(parameters['Ключ API (обязательно)']); // Извлекаем ключ API из параметров
var snapshotKey = Number(parameters['Горячая клавиша']); // Извлекаем код горячей клавиши из параметров
var includeVariables = (String(parameters['Отправлять переменные?']) == 'да' ? true : false); // Приводим параметр к типу bool
if(apiKey == '') {
alert('Упс! Вы забыли задать ключ API в настройках плагина BugReporter!'); // Выдаём предупреждение, если автор игры забыл указать ключ
return; // Завершаем выполнение
}
var overlayOpened = false; // Признак открытого оверлея
var popupTimeout = null; // Переменная для таймаута попапа
if(!('resume' in SceneManager)) { // Если в SceneManager нет метода resume - добавляем его
SceneManager.resume = function() { // Сделано для совместимости со старыми версиями мейкера, на новых (1.5.0+) исполняться не будет
this._stopped = false;
this.requestUpdate();
if(!Utils.isMobileSafari()) {
this._currentTime = performance.now();
this._accumulator = 0;
}
};
}
var oldFunc = Input._shouldPreventDefault; // Получаем функцию ядра, блокирующую обработку Backspace и стрелок
Input._shouldPreventDefault = function(keyCode) { // Оборачиваем её в нашу прослойку
if(overlayOpened) return false; // Если открыт оверлей - не блокируем клавиши
oldFunc(keyCode); // Если оверлей закрыт - выполняем функцию ядра как обычно
}
var resultPopup = document.createElement('div');
var overlay = document.createElement('div'); // Создаём все DOM-элементы
var overlayWindow = document.createElement('div');
var nicknameLabel = document.createElement('label');
var nicknameField = document.createElement('input');
var descrLabel = document.createElement('label');
var descrTextarea = document.createElement('textarea');
var cancelButton = document.createElement('a');
var submitButton = document.createElement('button');
resultPopup.innerHTML = '✔';
resultPopup.style.display = 'none';
resultPopup.style.position = 'absolute';
resultPopup.style.padding = '10px';
resultPopup.style.left = '10px';
resultPopup.style.top = '10px';
resultPopup.style.background = '#a6f086';
overlay.style.display = 'none'; // Стилизуем DOM элементы
overlay.style.alignItems = 'center';
overlay.style.justifyContent = 'center';
overlay.style.position = 'absolute';
overlay.style.left = '0px';
overlay.style.top = '0px';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.background = 'rgba(0, 0, 0, 0.5)';
overlayWindow.style.padding = '10px';
overlayWindow.style.width = '300px';
overlayWindow.style.background = '#fff';
nicknameLabel.style.display = 'block';
nicknameField.id = 'br_nickname';
nicknameField.style.float = 'right';
nicknameLabel.style.overflow = 'auto';
nicknameField.style.width = '200px';
descrLabel.style.display = 'block';
descrLabel.style.padding = '10px 0px 10px 0px';
descrTextarea.style.width = '98%';
descrTextarea.rows = 4;
descrTextarea.style.resize = 'none';
cancelButton.style.float = 'right';
cancelButton.style.cursor = 'pointer';
cancelButton.innerHTML = 'Отмена';
submitButton.style.cursor = 'pointer';
submitButton.innerHTML = 'Отправить';
document.body.appendChild(resultPopup); // Составляем структуру и добавляем в DOM
overlay.appendChild(overlayWindow);
overlayWindow.appendChild(nicknameLabel);
overlayWindow.appendChild(descrLabel);
overlayWindow.appendChild(cancelButton);
overlayWindow.appendChild(submitButton);
nicknameLabel.appendChild(nicknameField);
nicknameLabel.appendChild(document.createTextNode('Ваш ник: '));
descrLabel.appendChild(document.createTextNode('Комментарий к скриншоту:'));
descrLabel.appendChild(descrTextarea);
document.body.appendChild(overlay);
cancelButton.onclick = function(event) { // По нажатию на кнопку "Отмена"
closeOverlay(); // Убираем оверлей
}
submitButton.onclick = function(event) { // ПО нажатию на кнопку "Отправить"
sendReport(); // Отправляем отчёт
}
document.body.onkeydown = function(event) { // По нажатию клавиш клавиатуры
event = event || window.event; // Получаем событие (разные варианты для кроссбраузерности)
var keycode = event.charCode || event.keyCode; // Получаем код нажатой клавиши (разные варианты для кроссбраузерности)
switch(keycode) { // Проверяем код нажатой клавиши
case 8:
return true;
case snapshotKey: // Если нажатая клавиша соответствует заданной в настройках плагина
if(!overlayOpened) { // Если оверлей не открыт
openOverlay(); // Открываем оверлей
} else { // Если оверлей открыт
sendReport(); // Отправляем отчёт
}
break;
case 13: // Если это Enter
if(overlayOpened && document.activeElement == nicknameField) { // Если активно поле ввода никнейма
descrTextarea.focus(); // Ставим курсор на поле комментария
return false;
}
break;
case 27: // Если это Escape
if(overlayOpened) closeOverlay(); // Убираем оверлей
break;
}
}
function sendReport() { // Функция отправки отчёта
var base64Data = SceneManager.snap()._canvas.toDataURL('image/jpeg', 0.9); // Получаем скриншот в формате jpeg с качеством 90
var postData = {'act': 'save_report', 'api_key': apiKey, 'author': (nicknameField.value || ''), 'descr': (descrTextarea.value || descrTextarea.innerHTML || ''), 'image': base64Data}; // Создаём массив для POST-данных
var gameData = {}; // Создаём массив для данных игры
if(typeof $gameMap != 'undefined' && '_mapId' in $gameMap && $gameMap._mapId != 0) gameData.mapId = $gameMap._mapId; // Если задан id локации - добавляем его в данные игры
if(includeVariables) { // Если в настройках плагина включена отправка переменных
if(typeof $gameVariables != 'undefined' && '_data' in $gameVariables) { // Если массив переменных существует
var variableData = {}; // Создаём массив для данных переменных
$gameVariables._data.forEach(function(v, k) {
variableData[k] = [($dataSystem["variables"][k] || ''), v]; // Добавляем в массив переменных имя и текущее значение
});
if(Object.keys(variableData).length > 0) gameData["variables"] = variableData; // Если собрали хоть одну переменную - включаем в данные игры
}
if(typeof $gameSwitches != 'undefined' && '_data' in $gameSwitches) { // Если массив переключаетей существует
var switchData = {}; // Создаём массив для данных переключаетей
$gameSwitches._data.forEach(function(v, k) { // Перебираем включенные переключатели
switchData[k] = [($dataSystem["switches"][k] || ''), v]; // Добавляем в массив переключаетей имя и текущее значение
});
if(Object.keys(switchData).length > 0) gameData["switches"] = switchData; // Если собрали хоть один переключатель - включаем в данные игры
}
}
if(Object.keys(gameData).length > 0) { // Если собрали какие-либо данные игры
postData["game_data"] = JSON.stringify(gameData); // Преобразуем их в JSON и добавляем к POST-данным
}
post('https://bugreporter.4ky.ru', postData); // Отправляем POST-запрос на сервер
closeOverlay(); // Убираем оверлей
}
function openOverlay() { // Функция открытия оверлея
SceneManager.stop(); // Ставим игру на паузу
descrTextarea.value = ''; // Очищаем поле ввода комментария
overlay.style.display = 'flex'; // Отображаем оверлей
overlay.style.zIndex = '10001'; // Меняем приоритет оверлея (поверх всего)
if((!'value' in nicknameField) || nicknameField.value == '') { // Если поле с никнеймом пусто
nicknameField.focus(); // Ставим курсор на него
} else { // Если заполнено
descrTextarea.focus(); // Ставим курсор на поле комментария
}
overlayOpened = true; // Переключаем признак открытия оверлея
}
function closeOverlay() { // Функция закрытия оверлея
overlay.style.display = 'none'; // Скрываем оверлей
SceneManager.resume(); // Возобновляем игру
overlayOpened = false; // Переключаем признак открытия оверлея
}
function post(url, params) { // Функция отправки POST-запроса
var formData = new FormData(); // Создаём элмент для POST-данных
for(var k in params) { // Перебираем параметры
formData.append(k, params[k]); // Добавляем в POST-данные
}
var http = new XMLHttpRequest(); // Создаём элемент для отправки запроса
http.open('POST', url, true); // Открываем соединение
http.onreadystatechange = function() { // Задаём действия после отправки запроса
if(http.readyState == 4 && http.status == 200) { // Если запрос был успешен
if(http.response!='ok') { // Если результат не ОК
alert(http.response); // Показать ошибку
return;
}
resultPopup.style.display = 'block'; // Показываем попап
resultPopup.style.zIndex = '10000'; // Меняем приоритет попапа (поверх всего)
if(popupTimeout != null) clearTimeout(popupTimeout);
popupTimeout = setTimeout(function() {
resultPopup.style.display = 'none';
popupTimeout = null;
}, 1000);
}
}
http.send(formData); // Отправляем запрос
}
})();
Как использовать плагин (описание для новичков):
1. Регистрируемся на
bugreporter.4ky.ru и создаём страничку игры, копируем ключ API.
2.
Скачиваем плагин и помещаем в папку
js\plugins вашей игры.
3. Запускаем мейкер, жмём
F10,
Enter, выбираем из списка
BugRepoter, в правой части двойной клик по полю
Ключ API, вставляем ранее скопированный ключ, жмём ОК.
4. Ура, плагин подключен!
Технодемка:
Попробовать онлайн
Скачать
Освещение в демке добавлено только для теста совместимости и к этому плагину отношения не имеет!
Плагин должен быть совместим с любыми другими, а также поддерживает даже устаревшие версии мейкера (проверено на 1.2.0).
Посмотреть сделанные в технодемке скриншоты, описания и т.д. можно тут:
ССЫЛКА
p.s. Фух, успел доделать