Войти на сайт

Авторизация, ждите ...
×

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

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

  • mayday_45
  • mayday_45 аватар
  • Вне сайта
  • Познающий
  • Сообщений: 10
  • Спасибо получено: 4
Я конечно понимаю, что для этой нужды уже есть плагины, НО! Моя ситуация с маленьким подвохом :) В моей ситуации картинку стандартного фона сообщений необходимо изменить во время показа сообщений в своей созданной сцене, т.е. допустим, у меня по определенной команде начинается вывод нескольких сообщений подряд.
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:
Последнее редактирование: 3 года 2 нед. назад от mayday_45.
Администратор запретил публиковать записи гостям.

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

  • Dmy
  • Dmy аватар
  • Вне сайта
  • Заблокирован
  • Сообщений: 1142
  • Спасибо получено: 2477
  • 2 место УчительПроект месяца 3 местоРазработчикПаладинДаритель СтимкеяПрограммист RubyВетеранЗа 2 место на конкурсе маппингаОратор
$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();
Все эти команды просто добавляют текст в $gameMessage, в этот момент текст ещё даже не начал показываться.

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

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

В простейшем случае там будет что-то типа такого:
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, уже после того, как первая вывелась (вывелся ли прошлый текст мы проверяем через $gameMessage.isBusy()).

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

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

Вот пример реализации с массивом из анонимных функций Scene_Example.steps (это рабочий плагин, я проверял: оформление меняется):
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') не всегда возвращает загруженную картинку. Иногда он возвращает загружающуюся картинку, которая будет загружена когда-то в будущем. Поэтому имеет смысл загрузить картинку заранее.
Последнее редактирование: 3 года 2 нед. назад от Dmy.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Cabbit, VarVarKa, mayday_45

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

  • mayday_45
  • mayday_45 аватар
  • Вне сайта
  • Познающий
  • Сообщений: 10
  • Спасибо получено: 4
Спасибо за разъяснения, очень помогло!
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Dmy
Модераторы: NeKotZima
Время создания страницы: 0.212 секунд