- Сообщений: 10
- Спасибо получено: 4
Как изменить картинку заднего фона окна сообщений?
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;
};
.т.е. убираю рамки и ставлю назад свою картинку. Исправьте пожалуйста, если я меняю задний фон у окна сообщения неправильно
Так вот, если вставить последние две строки, меняющие фон по моему методу между командами $gameMessage.add("text 2") и $gameMessage.add("text 3"), то фон поменяется моментально, то есть сразу же на первом сообщении.
Возможно ли как-либо исправить этот момент, есть у кого соображения? Версия MV.
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;
};
.т.е. убираю рамки и ставлю назад свою картинку. Исправьте пожалуйста, если я меняю задний фон у окна сообщения неправильно
Так вот, если вставить последние две строки, меняющие фон по моему методу между командами $gameMessage.add("text 2") и $gameMessage.add("text 3"), то фон поменяется моментально, то есть сразу же на первом сообщении.
Последнее редактирование: 5 года 4 нед. назад пользователем mayday_45.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
5 года 4 нед. назад - 5 года 4 нед. назад #122137
от Dmy
Все эти команды просто добавляют текст в [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. Потом снова ждём и если надо, выводим следующий текст.
В простейшем случае там будет что-то типа такого:
Т.е. вторую часть (и третью потом) мы добавляем не при запуске сцены, а в update, уже после того, как первая вывелась (вывелся ли прошлый текст мы проверяем через [tt]$gameMessage.isBusy()[/tt]).
Делать один большой if не стоит, т.к. такой код сложно расширять (если нужно десять шагов, нужно 10 проверок внутри if'а — легко ошибиться с проверкой).
Вместо этого лучше создать массив из функций а внутри [tt]update[/tt] просто проверять «мы ещё запустили не все функции из массива? если не все, запустить следующую».
Вот пример реализации с массивом из анонимных функций [tt]Scene_Example.steps[/tt] (это рабочий плагин, я проверял: оформление меняется):
_______________________
Кстати, важный момент. Картинки загружаются не сразу. Так что будьте осторожны вот с этой строчкой:
this._messageWindow._windowBackSprite.bitmap = ImageManager.loadPicture('test_frame');
ImageManager.loadPicture('test_frame') не всегда возвращает загруженную картинку. Иногда он возвращает загружающуюся картинку, которая будет загружена когда-то в будущем. Поэтому имеет смысл загрузить картинку заранее.
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();
Нужно, чтобы смена рамки осуществлялась тогда, когда работа текста дойдёт до нужного текста.
Для этого нужно разнести добавление 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.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
5 года 3 нед. назад #122143
от mayday_45
mayday_45 ответил в теме Как изменить картинку заднего фона окна сообщений?
Спасибо за разъяснения, очень помогло!
Спасибо сказали: Dmy
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Время создания страницы: 0.096 секунд
