Как изменить картинку заднего фона окна сообщений?

Больше
5 года 4 нед. назад - 5 года 4 нед. назад #122134 от mayday_45
Я конечно понимаю, что для этой нужды уже есть плагины, НО! Моя ситуация с маленьким подвохом :) В моей ситуации картинку стандартного фона сообщений необходимо изменить во время показа сообщений в своей созданной сцене, т.е. допустим, у меня по определенной команде начинается вывод нескольких сообщений подряд.
SceneTest.prototype.CommandDialog = function (){
$gameMessage.add("text 1");
$gameMessage.newPage();
$gameMessage.add("text 2");
$gameMessage.newPage();
$gameMessage.add("text 3");
$gameMessage.newPage();
$gameMessage.add("text 4");
$gameMessage.newPage();
$gameMessage.add("text 5");
$gameMessage.newPage();
};
Мне необходимо сделать так, чтобы первые 2 сообщения выходили в стандартной "заводской" рамке, третье сообщение по нужде должно показаться с измененным фоном, а 4 и 5 сообщения возвращались к стандартной рамке. Какой способ замены фона я нашел:
SceneTest.prototype.createMessageWindow = function() {
this._messageWindow = new Window_Message();
this._messageWindow.width = 1000;
this.addWindow(this._messageWindow);
this._messageWindow.subWindows().forEach(function(window) {
this.addWindow(window);
}, this);
this._messageWindow.x = 355;
this._messageWindow._windowBackSprite.bitmap = ImageManager.loadPicture('test_frame');
this._messageWindow._windowFrameSprite.bitmap = null;
};
.т.е. убираю рамки и ставлю назад свою картинку. Исправьте пожалуйста, если я меняю задний фон у окна сообщения неправильно *facepalm*
Так вот, если вставить последние две строки, меняющие фон по моему методу между командами $gameMessage.add("text 2") и $gameMessage.add("text 3"), то фон поменяется моментально, то есть сразу же на первом сообщении. *facepalm* Возможно ли как-либо исправить этот момент, есть у кого соображения? Версия MV. :wall:
Последнее редактирование: 5 года 4 нед. назад пользователем mayday_45.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Ветеран Поддержка Фонда Разработчик Проект месяца 3 место Учитель Оратор Даритель Стимкея 2 место За 2 место на конкурсе маппинга Программист Ruby Паладин
Больше
5 года 4 нед. назад - 5 года 4 нед. назад #122137 от Dmy
Code:
$gameMessage.add("text 1"); $gameMessage.newPage(); $gameMessage.add("text 2"); $gameMessage.newPage(); $gameMessage.add("text 3"); $gameMessage.newPage(); $gameMessage.add("text 4"); $gameMessage.newPage(); $gameMessage.add("text 5"); $gameMessage.newPage();
Все эти команды просто добавляют текст в [tt]$gameMessage[/tt], в этот момент текст ещё даже не начал показываться.

Нужно, чтобы смена рамки осуществлялась тогда, когда работа текста дойдёт до нужного текста.

Для этого нужно разнести добавление text 3 и text 4, а потом text 5 и text 6 по времени. Т.е. в начале добавляем только text 1 и text 2. Потом ждём, когда они выведутся (в методе [tt]update[/tt] проверяем, когда [tt]$gameMessage.isBusy()[/tt] начнёт выдавать [tt]false[/tt]). Когда начало выдавать false, если мы ещё не выводили №3+№4 — выводим №3+№4. Потом снова ждём и если надо, выводим следующий текст.

В простейшем случае там будет что-то типа такого:
Code:
Scene_Example.prototype.update = function() { Scene_Base.prototype.update.call(this); if (this.isActive() && !$gameMessage.isBusy()) { if (!this.secondPartShown) { // Тут код смены оформления $gameMessage.add("text 3"); $gameMessage.newPage(); $gameMessage.add("text 4"); this.secondPartShown = true; } else if (!this.thirdPartShown) { // Тут код возвращения оформления $gameMessage.add("text 5"); $gameMessage.newPage(); $gameMessage.add("text 6"); this.thirdPartShown = true; } } }

Т.е. вторую часть (и третью потом) мы добавляем не при запуске сцены, а в update, уже после того, как первая вывелась (вывелся ли прошлый текст мы проверяем через [tt]$gameMessage.isBusy()[/tt]).

Делать один большой if не стоит, т.к. такой код сложно расширять (если нужно десять шагов, нужно 10 проверок внутри if'а — легко ошибиться с проверкой).

Вместо этого лучше создать массив из функций а внутри [tt]update[/tt] просто проверять «мы ещё запустили не все функции из массива? если не все, запустить следующую».

Вот пример реализации с массивом из анонимных функций [tt]Scene_Example.steps[/tt] (это рабочий плагин, я проверял: оформление меняется):
Code:
function Scene_Example() { this.initialize.apply(this, arguments); } Scene_Example.prototype = Object.create(Scene_Base.prototype); Scene_Example.prototype.constructor = Scene_Example; // Массив функций, которые будут выполняться поочерёдно // Я написал эту штуку без prototype, как общую для всех экземпляров, так что к ней // надо будет обращаться Scene_Example.steps, а не this.steps Scene_Example.steps = [ function () { $gameMessage.add("text 1"); $gameMessage.newPage(); $gameMessage.add("text 2"); }, function () { // Сохраним старые значения, чтобы мы могли их вернуть this.savedMsgWindowX = this._messageWindow.x; this.savedMsgWindowBackSprite = this._messageWindow._windowBackSprite.bitmap; this.savedMsgWindowFrameSprite = this._messageWindow._windowFrameSprite.bitmap; this._messageWindow.x = 355; this._messageWindow._windowBackSprite.bitmap = this.alternateWindowFrame; this._messageWindow._windowFrameSprite.bitmap = null; $gameMessage.add("text 3"); $gameMessage.newPage(); $gameMessage.add("text 4"); }, function () { // Вернём старые значения this._messageWindow.x = this.savedMsgWindowX; this._messageWindow._windowBackSprite.bitmap = this.savedMsgWindowBackSprite; this._messageWindow._windowFrameSprite.bitmap = this.savedMsgWindowFrameSprite; $gameMessage.add("text 5"); $gameMessage.newPage(); $gameMessage.add("text 6"); } ]; Scene_Example.prototype.create = function() { Scene_Base.prototype.create.call(this); this.createWindowLayer(); this.createMessageWindow(); this.currentStep = 0; // Начну загрузку фона окна в начале сцены — так больше шансов, что он // загрузится к моменту показа this.alternateWindowFrame = ImageManager.loadPicture('test_frame'); }; Scene_Example.prototype.start = function () { Scene_Base.prototype.start.call(this); //Вызываем первую функцию this.nextStep(); } // Метод, которая будет загружать следующую функцию из массива steps Scene_Example.prototype.nextStep = function () { var step = Scene_Example.steps[this.currentStep]; // Вызываем через .call, чтобы this внутри функции был равен // экземпляру Scene_Example step.call(this); // Увеличиваем currentStep на 1, чтобы дальше читался следующий шаг this.currentStep++; } Scene_Example.prototype.update = function() { Scene_Base.prototype.update.call(this); if (this.currentStep < Scene_Example.steps.length) { if (this.isActive() && !$gameMessage.isBusy()) { this.nextStep(); } } else { // Я вынес основной код update, который выполняется после того, как действия // из всех функций массива steps выполнены, в другую функцию, //updateAfterSteps, чтобы код был проще this.updateAfterSteps(); } } // Метод, который вызывается из update после того, как все функции из steps выполнены Scene_Example.prototype.updateAfterSteps = function () { // Тут код после показа всего // Для примера сделаем после показа всего закрытие по эксейпу if (this.isActive() && Input.isPressed('escape')) { this.popScene(); } } Scene_Example.prototype.createMessageWindow = function() { this._messageWindow = new Window_Message(); this.addWindow(this._messageWindow); this._messageWindow.subWindows().forEach(function(window) { this.addWindow(window); }, this); };

_______________________

Кстати, важный момент. Картинки загружаются не сразу. Так что будьте осторожны вот с этой строчкой:

this._messageWindow._windowBackSprite.bitmap = ImageManager.loadPicture('test_frame');

ImageManager.loadPicture('test_frame') не всегда возвращает загруженную картинку. Иногда он возвращает загружающуюся картинку, которая будет загружена когда-то в будущем. Поэтому имеет смысл загрузить картинку заранее.
Последнее редактирование: 5 года 4 нед. назад пользователем Dmy.
Спасибо сказали: Cabbit, VarVarKa, mayday_45

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
5 года 3 нед. назад #122143 от mayday_45
Спасибо за разъяснения, очень помогло!
Спасибо сказали: Dmy

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Время создания страницы: 0.096 секунд
Работает на Kunena форум