Войти на сайт

Авторизация, ждите ...
×
Правила раздела:
1 Задавайте конкретные вопросы. Для болтовни есть свободный раздел.
2 По возможности давайте конкретные ответы.
3 Один вопрос=одна тема. Если хотите задать ещё вопрос, то начинайте новую тему.
4 Название темы должно составлять сам вопрос, и быть максимально конкретным. Рекомендуется начинать тему словами "Как", "Что", "Почему". А первый пост повторяет вопрос и даёт расширенные сведения.
5 Рекомендуется указывать версию мейкера (2000, 2003, RMXP, RMVX, ACE, IGM, и.т.д.. Это важно, и всё равно ведь спросят.
6 Темы "Пара вопросов", "Помогите", и подобные им - самый лёгкий путь к бану.
7 Поиск находится вверху справа.
А. Названия подразделов этого раздела уточняются. Советы принимаются.
  • Страница:
  • 1
  • 2

ТЕМА: MV 1.6: Что нового?

MV 1.6: Что нового? 8 мес. 3 нед. назад #102735

  • Mur
  • Mur аватар
  • Вне сайта
  • Просветлённый
  • Мур? Мур! Мур.
  • Сообщений: 435
  • Спасибо получено: 1044
  • 2 место Программист JavaScript Организатор конкурсовДаритель СтимкеяУчитель
EvilCat пишет:
Мне не хватает знания об устройстве плагина, чтобы ответить точно...

Да по сути ничего в нём и нет:
var MUR = MUR || {};			// MUR's main object
MUR.NPC = MUR.NPC || {};		// Plugins's stuff
 
MUR.NPC.block_handler = function (data, step, force) {
 
bla bla bla…
 
}

И всё! Я уже могу обращаться к MUR.NPC.block_handler() и всё работает. Собственно вопрос-то и был, в том, что достаточно создать объект {} и можно «пихать» в него что угодно? o_O в том числе и функции?

И сразу второй вопрос, а что будет если я потом захочу переопределить эту фукнцию, как раньше мы делали с базовыми классами?
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	_Game_Interpreter_pluginCommand.call(this, command, args);
 
	bla bla bla
};

И у меня есть подозрения, что у меня это не получится сделать ~_~'

EvilCat пишет:
Просто перескажу, как работают прототипы.

Ох! А можно просто примерчик, как всё-таки ПРАВИЛЬНО оформить свой плагин в виде класса, что бы в последствии можно было наследовать и менять методы?

Я просто помню, что вот была такая конструкция, делаем свою новую сцену(Scene_Achievements) наследуя её от Scene_ItemBase:
function Scene_Achievements() {
	this.initialize.apply(this, arguments);
}
 
Scene_Achievements.prototype = Object.create(Scene_ItemBase.prototype);
Scene_Achievements.prototype.constructor = Scene_Achievements;
 
Scene_Achievements.prototype.initialize = function() {
	Scene_ItemBase.prototype.initialize.call(this);
};
 
Scene_Achievements.prototype.create = function() {
	Scene_ItemBase.prototype.create.call(this);
	this.achievementsInit();
};
 
Scene_Achievements.prototype.achievementsInit = function() {
	....
};

Но это если мы наследуем. А если я просто делаю свой базовый класс? Что тогда указывать в качестве родителя? Ничего? Будет так работать?
Scene_Achievements.prototype = Object.create();
Последнее редактирование: 8 мес. 3 нед. назад от Mur.
Администратор запретил публиковать записи гостям.

MV 1.6: Что нового? 8 мес. 3 нед. назад #102736

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

То есть, если нам нужен совершенно уникальный объект, который будет всегда в одном экземпляре, никогда не будет создан новый и никогда ничего от него не унаследовано, то всегда можно было написать:
var God = {}
 
God.doSomething = function () { ... }

...а потом вызывать God.doSomething(). Никакого класса, никаких прототипов.

Но если необходимо наследование (или если воображаешь, что кому-то из игроделов-пользователей плагина захочется унаследовать от него свой), то да, наследование в Яваскрипте делается с помощью прототипов. А именно - если взять нашего Кота и его СемействоКошачьих, то у прототипа СемействаКошачьих тоже может быть свой конструктор ОтрядХищных, а у него прототип, и так далее по цепочке... Поиск полей объекта идёт по цепочке прототипов, пока та не закончится. Это и есть наследование.
Scene_Achievements.prototype = Object.create(Scene_ItemBase.prototype);
Scene_Achievements.prototype.constructor = Scene_Achievements;

Эти строчки как раз делают следующее:
  1. Объект Scene_Achievements.prototype создаётся как пустой объект, прототипом которого является Scene_ItemBase.prototype. У него пока нет своих полей, но как и Кот, нехватающие поля он пойдёт искать в Scene_ItemBase.prototype.
  2. Поскольку мы создали Scene_Achievements.prototype не через new, а через Object.create, он не знает свой конструктор... Поэтому мы ставим ему правильный конструктор.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Mur

MV 1.6: Что нового? 8 мес. 3 нед. назад #102737

  • Mur
  • Mur аватар
  • Вне сайта
  • Просветлённый
  • Мур? Мур! Мур.
  • Сообщений: 435
  • Спасибо получено: 1044
  • 2 место Программист JavaScript Организатор конкурсовДаритель СтимкеяУчитель
Уффф! Покопавшись на страницах developer.mozilla.org на меня нашло озарение, как это теперь может выглядеть плагин, начиная с MV 1.6

Сначала создаём базовый класс. В данном примере он просто сохраняет в переменную value на этапе инициализации (создания):
'use strict';
 
class MurBase {
	constructor(value) {
		this.value = value;
	}
}

Затем мы создаём «дитёнка» с родительскими свойствами, но расширяем функционал возможностью чтения/изменения переменной value, а так же добавляем метод log для вывода сообщения в отладчик:
class MurChild extends MurBase {
	constructor(value) {
		super(value + " & " + value);
	}
	get val() {
		return this.value;
	}
 
	set val(value) {
		this.value = value + " & " + value;
	}
 
	log (msg) {
		console.log(msg);
	}
}

Теперь самое время создать наш новый объект:
var mc = new MurChild("Test!");

Ну теперь к нему можно обращаться внутри базовых классов мейкера:
var _MurTest_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	_MurTest_Game_Interpreter_pluginCommand.call(this, command, args);
	if (command.toLowerCase() === "npc_speech") {
		mc.log(mc.val);
		mc.val = "Boom!";
		mc.log(mc.val);
	}
}

В идеале конечно было бы классно как-то скрестить ужа с ежом новое описание в стиле class и старое через prototype, что бы не городить огород с этими переопределениями функции, как-то pluginCommand. Но пока у меня нехватает знаний и понятий как эт вообще всё работает ~_~' все эксперименты больше по наитию «а что если сделать вот так? Ух-ты! Работает!» :blush:

С нетерпением жду идей по улучшению данного безобразия! :whistle:
Администратор запретил публиковать записи гостям.

MV 1.6: Что нового? 8 мес. 3 нед. назад #102745

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 843
  • 3 место ГотвУчитель2 место
Всё правильно, только при классовой нотации придётся учитывать ограничение по обращению к this в конструкторе до вызова super, которое уже обсуждали, ну, или стыдливо обходить его с помощью перекладывания функционала конструктора на какой-нибудь initialize >_<
Последнее редактирование: 8 мес. 3 нед. назад от EvilCat.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Mur
  • Страница:
  • 1
  • 2
Время создания страницы: 0.223 секунд