Как создать окно сообщения в собственной сцене?

Больше
5 года 1 мес. назад #122044 от mayday_45
Всем привет, форумчане:) Допустим, у меня есть своя сцена. В ней есть кнопочка, которая по идее должна начинать открывать серию последовательных окон с сообщениями и картинками говорящих, как по команде $gameMessage.add("мой текст"). Проблема в том, что данная команда начинает работать только когда я закрываю свою сцену. Как это фиксить, есть у кого соображения? Если я не ошибаюсь, нужно создавать новое окно в своей сцене с прототипом window_message, или нет? Но как это правильно сделать? Долго искал примеры, но не нашел :wall:
Спасибо сказали: Dmy

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

Разработчик
Больше
5 года 1 мес. назад #122047 от Marganec
чего...?извини,но...можно попонятнее?

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

Победитель конкурса Учитель
Больше
5 года 1 мес. назад #122049 от 123th

mayday_45 пишет: Всем привет, форумчане:) Допустим, у меня есть своя сцена. В ней есть кнопочка, которая по идее должна начинать открывать серию последовательных окон с сообщениями и картинками говорящих, как по команде $gameMessage.add("мой текст"). Проблема в том, что данная команда начинает работать только когда я закрываю свою сцену. Как это фиксить, есть у кого соображения? Если я не ошибаюсь, нужно создавать новое окно в своей сцене с прототипом window_message, или нет? Но как это правильно сделать? Долго искал примеры, но не нашел :wall:


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

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

Ветеран Поддержка Фонда Разработчик Проект месяца 3 место Учитель Оратор Даритель Стимкея 2 место За 2 место на конкурсе маппинга Программист Ruby Паладин
Больше
5 года 1 мес. назад - 5 года 1 мес. назад #122050 от Dmy

mayday_45 пишет: Как это фиксить, есть у кого соображения? Если я не ошибаюсь, нужно создавать новое окно в своей сцене с прототипом window_message, или нет? Но как это правильно сделать? Долго искал примеры, но не нашел :wall:

Да, [tt]$gameMessage[/tt] — это модель. Она не отображает текст, а лишь хранит его (вместе с лицами, оформлением, информацией о том, что нужно показать выбор, ввод числа и т.п.).

За отображение действительно отвечает класс [tt]Window_Message[/tt] (это основное окно с текстом) и его помощники:
  • [tt]Window_ChoiceList[/tt] (окно выбора вариантов),
  • [tt]Window_NumberInput[/tt] (окно ввода числа),
  • [tt]Window_EventItem[/tt] (окно выбора предмета),
  • [tt]Window_Gold[/tt] (окно показа денег — используется для кода [tt]\$[/tt] в сообщении),
  • а в MZ ещё и [tt]Window_NameBox[/tt] (окно имени возле сообщения)

Соответственно, нужно создать эти окна. Как это делается, можно подглядеть в [tt]Scene_Map[/tt] и [tt]Scene_Base[/tt].

Здесь важно отметить, что окна создаются по-разному в MV и MZ:
  • В RPG Maker MV за создание всех окон отвечает окно [tt]Window_Message[/tt]. Оно создаёт все остальные окна-помощники, и их нужно только добавить на сцену.
  • В RPG Maker MZ сцены, в которых есть стандартный функционал сообщений, наследуются от [tt]Scene_Message[/tt]. [tt]Scene_Message[/tt] создаёт все окна: и [tt]Window_Message[/tt], и окна-помощники. И само добавляет их на сцену.

Это раздел про RPG Maker MV, поэтому ниже я пишу про RPG Maker MV. (Если нужна поддержка MZ, создайте отдельную тему, я отвечу.)

В RPG Maker MV для создания окна сообщения нужно выполнить такие действия:

1. Создать слой для окон (без этого вызовы [tt]addWindow[/tt] будут возвращать ошибку) вызовом [tt]this.createWindowLayer();[/tt] — эта функция определена в [tt]Scene_Base[/tt].

2. Создать объект [tt]Window_Message[/tt], добавить его на сцену через [tt]this.addWindow[/tt]. Желательно сохранить этот экземпляр [tt]Window_Message[/tt] куда-то (например, в [tt]this._messageWindow[/tt], как в стандартных сценах), т.к. он понадобится в будущем.

3. А также добавить все окна-помощники на сцену (метод [tt]subWindows()[/tt] у экземпляра [tt]Window_Message[/tt] возвращает массив окон-помощников). Пример можно посмотреть в функции createMessageWindow класса Scene_Battle (собственно, её можно прямо в свой код прихватизировать).

Всё! После этого сообщения будут отображаться. Но ещё такой момент — нужно, чтобы в остальной сцене не выполнялись действия в то время, пока активно окно сообщения. Иначе окажется, что кнопка Enter выполняет сразу два действия: и переходит к следующему сообщению, и делает что-то на сцене. Т.е. нужно добавить проверку.

Проверки такие:
  • Функция [tt]$gameMessage.isBusy()[/tt] показывает, хранится ли в [tt]$gameMessage[/tt] какой-то ещё не показанный текст.
  • Функция [tt]isClosing()[/tt] у экземпляра [tt]Window_Message[/tt] проверяет, что окно находится в процессе закрывания (если это не проверить, то кнопка Enter или Escape, закрывшая окно, сразу же может выполнить какое-то другое действие в том же кадре).

Почти всегда нужно делать сразу обе проверки — и [tt]$gameMessage.isBusy()[/tt], и [tt]this._messageWindow.isClosing()[/tt] (вместо [tt]this._messageWindow[/tt] подставьте своё, если вы сохранили экземпляр [tt]Window_Message[/tt] в другом месте).

Вот код-пример:
Code:
function Scene_Example() { this.initialize.apply(this, arguments); } Scene_Example.prototype = Object.create(Scene_Base.prototype); Scene_Example.prototype.constructor = Scene_Example; Scene_Example.prototype.create = function() { Scene_Base.prototype.create.call(this); this.createWindowLayer(); this.createMessageWindow(); }; Scene_Example.prototype.start = function () { Scene_Base.prototype.start.call(this); //Просто пример, чтобы был какой-то текст. Вероятно, в вашем случае текст надо //будет создать иначе. $gameMessage.add('Строка для проверки.') $gameMessage.add('Просто чтобы проверить, что что-то выводится.') } Scene_Example.prototype.update = function() { Scene_Base.prototype.update.call(this); //Если нажат Escape или X, закрыть сцену. Просто чтобы был способ из неё выйти //(в вашем примере, вероятно, нужно будет какое-то другое условие закрытия) if (this.isActive() && !$gameMessage.isBusy() && !this._messageWindow.isClosing() && 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); };

NB. Чтобы перейти на эту сцену-пример, можно поставить событие с командой «Скрипт», и в ней написать код [tt]SceneManager.push(Scene_Example)[/tt]


Marganec пишет: чего...?извини,но...можно попонятнее?

Это вопрос по программированию. Если ты не разбираешься в программировании, то ты не поймёшь вопроса — это нормально. Если хочешь научиться программировать, можешь попробовать начать с уроков Mur . А вопросы по ним (и по другим урокам) можно задавать на форуме.



123th пишет: всё делается через вывод картинок, в том числе текст. так что не извращайся и сразу выводи всё картинками.
всмысле картинками через скрипт.
паузу до стирания картинки можно сделать выведя пустое текстовое сообщение.

Картинками задолбаешься делать показ сообщения по буквам и парсинг текстовых кодов, как в стандартном [tt]Window_Message[/tt]. Если нужен «нативный» внешний вид сообщения, то лучше всё-таки создать [tt]Window_Message[/tt].

Да и проще это.
Последнее редактирование: 5 года 1 мес. назад пользователем Dmy.
Спасибо сказали: Cabbit, mayday_45

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

Больше
5 года 1 мес. назад - 5 года 1 мес. назад #122068 от mayday_45
0_0 Я даже не ожидал, что тут могут так развернуто ответить 0_0
Спасибо огромное за такие подробные разъяснения!) с этим вопросом разобрался только благодаря ответу Dmy) Но от себя еще добавлю, что для того, чтобы текст выходил с разных последовательно выходящих окнах, нужно между командами прописать $gameMessage.newPage(). Пример:
$gameMessage.add('первое сообщение');//выводится первое окно с текстом
$gameMessage.newPage();
$gameMessage.add('второе сообщение');//после закрытия первого окна выходит второе окно, но с другим текстом
Вдруг кому пригодится. По крайней мере, у меня это работает:)
Последнее редактирование: 5 года 1 мес. назад пользователем mayday_45.

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

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