Войти на сайт

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

ТЕМА: Не поддается обновление сцены вручную

Не поддается обновление сцены вручную 8 года 11 мес. назад #87824

  • Logan
  • Logan аватар
  • Вне сайта
  • Познающий
  • Сообщений: 11
  • Спасибо получено: 3
Вношу дополнения в плагин, который, изменяет внешний вид окна Статуса героев.
Пытаюсь через свою функцию вызвать обновление информации в окне, не загружая это же окно по-новой.
Но что-то я недопонял в синтаксисе и сломал голову об следующую ошибку:

Упрощенная часть кода:
    /// Моя функция:
	LMV_CharacterProfileScene.prototype.manualRun = function() {		
		LMV_CharacterProfileScene.prototype.nextIndex();
	};
///
 
	LMV_CharacterProfileScene.prototype.nextIndex = function()
    {
        ++ this._index;
        if($gameSystem._characterOnProfile[this._index] === undefined || $gameSystem._characterOnProfile[this._index] === null) this._index = 0;
        this.refreshActor();
    }
 
		LMV_CharacterProfileScene.prototype.refreshActor = function() {
        this._statusWindow.setActor($gameSystem._characterOnProfile[this._index]);
        this._statusWindow.activate();
    };

То есть, я пытаюсь вызвать nextIndex(), который в свою очередь запускает this.refreshActor(), который выдает ошибку при обращении к setActor:
TypeError: Cannot read property 'setActor' of undefined
    at LMV_CharacterProfileScene.refreshActor

Не могу понять, почему эта ошибка появляется, так как эти же функции исправно обрабатываются при инициализации сцены? И нет ошибок, если ткнуть в эту клавишу, что меня еще больше запутывает:
...
this._statusWindow.setHandler('pagedown', this.nextIndex.bind(this));
...
Последнее редактирование: 8 года 11 мес. назад от Logan.
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87825

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 2 место Учитель3 место Готв
Похоже, это типичный случай потери контекста - распространённая специфическая ошибка в Яваскрипте при начале его изучения.

При вызове метода его контекст (содержимое this) задаётся не тем, как был объявлен метод и где хранится, а тем, как он был вызван. Например, такая конструкция:
var obj=
{
 f: function() { console.log(this); }
}
 
var obj2={}
obj2.method=obj.f;
var f=obj.f;
 
obj.f();
obj2.method();
f();

В этом коде создаётся объект с методом f, который печатает в консоль контекст вызова. Затем создаётся ещё один объект, и в его поле method записывается метод f первого объекта. Затем поочерёдно этот метод вызывается у первого объекта, у второго и самостоятельно. В консоли будет видно, что содержимое this определяется тем, что стоит слева от точки при вызове; и в последнем случае оно будет пустым.
this._statusWindow.setHandler('pagedown', this.nextIndex.bind(this));

Здесь в качестве хендлера устанавливается не сам метод nextIndex, а его вызов с заданным контекстом. Именно этот вызов возвращает bind(this). Такую привязку приходится делать в Яваскрипте довольно часто.

Посмотри свой код. Где-то искомый метод вызывается без контекста или с неправильным контекстом слева от точки.

Ну точно. Нужно исправить так:
LMV_CharacterProfileScene.prototype.manualRun = function() {		
		this.nextIndex();
	};

См. мануалы call, apply, bind.
Последнее редактирование: 8 года 11 мес. назад от EvilCat.
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87827

  • Logan
  • Logan аватар
  • Вне сайта
  • Познающий
  • Сообщений: 11
  • Спасибо получено: 3
Спасибо за мануалы, повкуриваю.

EvilCat пишет:
Ну точно. Нужно исправить так:
LMV_CharacterProfileScene.prototype.manualRun = function() {		
		this.nextIndex();
	};

Не помогло, та же ошибка:

4.jpg



Вариант
LMV_CharacterProfileScene.prototype.nextIndex.call(this);
то же эту ошибку выдает.
Последнее редактирование: 8 года 11 мес. назад от Logan.
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87842

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 2 место Учитель3 место Готв
Ну, теперь-то this точно должен быть правильный... Раньше он был объектом-прототипом вместо искомого объекта.

Значит, в этой строчке
this._statusWindow.setActor($gameSystem._characterOnProfile[this._index]);

this._statusWindow разрешается как undefined, то есть, поле не задано. Я бы поставила там останов и посмотрела, что там действительно есть у контекстного объекта.
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87855

  • Logan
  • Logan аватар
  • Вне сайта
  • Познающий
  • Сообщений: 11
  • Спасибо получено: 3
EvilCat пишет:
this._statusWindow.setActor($gameSystem._characterOnProfile[this._index]);

this._statusWindow разрешается как undefined, то есть, поле не задано.

Не понял, то есть, он определен при инициализации, но не при вызове из моей функции?

EvilCat пишет:
Я бы поставила там останов и посмотрела, что там действительно есть у контекстного объекта.
Oк. Как это сделать?
Последнее редактирование: 8 года 11 мес. назад от Logan.
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87856

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 2 место Учитель3 место Готв
Не понял, то есть, он определен при инициализации, но не при вызове из моей фунуции?

В Яваскрипте очень мало понятия о приватности, так что если он при вызове функции не определяется, то разве что если он был удалён в какой-то момент после инициализации...
Ок. Как это сделать?

Во время прогона игры нажми F8, чтобы показать отладчик (ну, это ты явно уже знаешь). В отладчике есть вкладка Sources, где находятся исходники скриптов. В js/plugins найди свой плагин и нужную строчку. Ты можешь даже перейти на неё автоматически из сообщения об ошибке в консоли. Кликни сбоку (слева) от строчки два раза, чтобы поставить там останов. Или, кажется, можно кликнуть правой кнопкой мыши на строчку и выбрать "Toggle Breakpoint". После этого нажми F5, чтобы перезапустить игру (не закрывай её вручную, потому что тогда все настройки отладчика сбросятся).

Когда игра дойдёт до отмеченной строчки, она остановится: ты увидишь это в отладчике. Сбоку будет панель текущими значениями разных переменных - локально объявленных и значение this... Ещё там будет стёк вызовов, а сверху - панелька Watch, где вообще можно ввести любые выражения и названия переменных, чтобы подсмотреть их. Массивы и объекты можно раскрывать, чтобы смотреть их содержимое. В общем, таким образом можно получить, что именно данный вызов считает за this и есть ли у него _statusWindow.

Единственная трудность может возникнуть в том, что иногда MV запускает те или иные плагины в "виртуальной машине". Не знаю, когда и зачем, но тогда остановы не действуют. Отличить виртуальную машину можно по тому, что лист с кодом будет жёлтого цвета, а сверху около названия файла будет написано "VM". Кажется, он делает это довольно бессистемно, возможно, в зависимости от тормозов или количество обращений к скрипту.

Если ты сможешь дать мне код или проект в целом, я с интересом попробую найти ошибку.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: RastaManGames, KageDesu, Logan

Не поддается обновление сцены вручную 8 года 11 мес. назад #87857

  • Logan
  • Logan аватар
  • Вне сайта
  • Познающий
  • Сообщений: 11
  • Спасибо получено: 3
Если есть желание посмотреть на код в целом, лучше выложу проект) По-немногу выявление проблемы затянется на длинную переписку.

www.dropbox.com/s/pcnt6tc3yb2uhzl/Test.exe?dl=0

Я убрал из проекта все лишние плагины, очистил карты - оставил то, что относится к вопросу.


Думаю, с комментариями все будет понятно, что я делал, но опишу на всякий случай:

Старался я добавить в плагин Профилей окно с выбором персонажей из другого плагина. Своим нубским кодингом заставил окно работать, затем пытался связать выбор необходимого персонажа с обновлением информации о нем. То есть, менять номер требуемого актера и запускать refreshActor. В результате мой франкенштейн стал выводить ошибки, поэтому, я пробовал различные комбинации, обращался к другим плагинам и т.д и т.п. - то, что закомменченно в строках 390-393 - это мусор от попыток, не имеет смысла для этого плагина.

Закончил тем, что стал вызывать функции плагина, которые, как я думал, по умолчанию должны работать - то есть вызывать следующего персонажа, по порядку нумерации. Это стало вызывать те же ошибки, что при моих изначальных попытках.
Ошибка появляется при выборе первого персонажа, с остальными код еще не связыван.

Номера строк с моим кодом:
276
320
347

Я весь за, если появится желание доработать плагин.
Последнее редактирование: 8 года 11 мес. назад от Logan.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: RastaManGames

Не поддается обновление сцены вручную 8 года 11 мес. назад #87862

  • KageDesu
  • KageDesu аватар
  • Вне сайта
  • Мастер
  • Сообщений: 101
  • Спасибо получено: 346
Привет, Logan.
Проблема твоя была не в функции, а в её вызове.

В строке 384: if (v == 0){LMV_CharacterProfileScene.prototype.manualRun();} - так делать нельзя.
Получается ты вызываешь метод класса LMV_CharacterProfileScene, а надо метод объекта класса.

Поменяй строку 384 на такую: if (v == 0){this.stage.manualRun();}
В данном контексте stage - это сцена родитель, т.е. объект LMV_CharacterProfileScene.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Logan

Не поддается обновление сцены вручную 8 года 11 мес. назад #87864

  • Logan
  • Logan аватар
  • Вне сайта
  • Познающий
  • Сообщений: 11
  • Спасибо получено: 3
Заработало, спасибо большое!
Администратор запретил публиковать записи гостям.

Не поддается обновление сцены вручную 8 года 11 мес. назад #87869

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 2 место Учитель3 место Готв
Спасибо, KageDesu! А я даже посмотреть не успела %)
Администратор запретил публиковать записи гостям.
Модераторы: NeKotZima
Время создания страницы: 0.264 секунд