Desenvolvedor FullStack
Introdução
Nesse tutorial iremos criar um plugin para adicionar uma nova janela customizada no RPG MAKER MV/MZ.Requisitos
Conteúdo
Olá a todos vocês, espero que estejam bem!
Resolvi experimentar criar esse tipo de conteúdo para ver se consigo transmitir conhecimento e ensinar algumas coisas legais. Para começar vamos criar uma janela a pedido do @DadoCWB, a criação de janelas é um tema muito recorrente para os iniciantes em programação no RPG MAKER, elas ajudam a exibir informações ao usuário, e muitos plugins utilizam esse recurso, imagine ter uma janela de opções para parametrizar o seu plugin, maneiro né? agora vamos começar a codificação.
Resolvi experimentar criar esse tipo de conteúdo para ver se consigo transmitir conhecimento e ensinar algumas coisas legais. Para começar vamos criar uma janela a pedido do @DadoCWB, a criação de janelas é um tema muito recorrente para os iniciantes em programação no RPG MAKER, elas ajudam a exibir informações ao usuário, e muitos plugins utilizam esse recurso, imagine ter uma janela de opções para parametrizar o seu plugin, maneiro né? agora vamos começar a codificação.
DISCLAIMER |
Esse tutorial pode ser consumido por qualquer pessoa que tenha interesse na área de programação, ele foi escrito e pensado para pessoas com qualquer nível de experiencia profissional. |
Primeiro acesse o Visual Studio Code e abra a pasta do seu projeto.
Crie um novo arquivo chamado "CustomWindow.js", dentro da pasta JS > Plugins.
Agora que já temos nosso arquivo, vamos adicionar o seguinte trecho de código:
Javascript:
(function () {
'use strict';
})();
Criamos uma função que será executada automaticamente e definimos "use strict", o strict mode faz várias mudanças nas semânticas normais do JavaScript. Primeiro, o strict mode elimina alguns erros silenciosos do JavaScript fazendo-os lançar exceções. Segundo, o strict mode evita equívocos que dificultam que motores JavaScript realizem otimizações: código strict mode pode às vezes ser feito para executar mais rápido que código idêntico não-strict mode. Terceiro, strict mode proíbe algumas sintaxes que provavelmente serão definidas em versões futuras do ECMAScript.
Entendo a Window_Base
A Window_Base é usada como a base de toda janela criada no maker, digamos que ela seja a mãe das janelas, na programação orientada a objetos nos chamamos esse comportamento de Parent and Child, ou seja, existe o vinculo entre as classes e isso se chama Herança, com o javascript podemos passar as heranças usando funções de prototipo, veja esse trecho de código:
Javascript:
Window_Base.prototype = Object.create(Window.prototype);
Window_Base.prototype.constructor = Window_Base;
Primero é criado a função prototipada a partir do método Object.create() que criará um novo objeto com base no Window.prototype que foi passado como parâmetro, dessa forma a Window_Base.prototype receberá todos os métodos também definidos em Window, criando assim a relação de Parent and Child, e por fim temos a mudança do Constructor que será responsavel por definir a autoria dos métodos criados a partir de Window_Base.prototype, se não mudarmos isso todos os métodos gerados em Window_Base passariam a ser de autoria de Window.
Entenda a seguinte declaração:
Entenda a seguinte declaração:
Javascript:
function Window_Base() {
this.initialize(...arguments);
}
Window_Base.prototype.initialize = function(rect) {
Window.prototype.initialize.call(this);
this.loadWindowskin();
this.checkRectObject(rect);
this.move(rect.x, rect.y, rect.width, rect.height);
this.updatePadding();
this.updateBackOpacity();
this.updateTone();
this.createContents();
this._opening = false;
this._closing = false;
this._dimmerSprite = null;
};
A função é criada normalmente, porem existe a chamada do método Initialize passando os Arguments da função usando a sintaxe Spread, mas agora você deve se perguntar a onde você defini esses "Arguments", bem veja que existe dentro do método "Window_Base.prototype.initialize" a seguinte declaração "function(rect)", ou seja existe 1 (um) argumento: rect. Existe a seguinte invocação "Window.prototype.initialize.call(this);", existe um motivo de ela está no topo do bloco da função, essa invocação tem como objetivo fazer com que o Parent execute seu método Initialize usando o this, se atente a essa palavra, pois ela é reservada e faz referência clara a função na qual o bloco de código se encontra. Perceba que o método foi chamado usando o .call(this), dessa maneira this (Window) passa a ser this (Window_Base).
Criando nossa Window_Custom
Vamos criar nossa Window a partir da Window_Gold, veja o trecho a seguir:
Javascript:
//-----------------------------------------------------------------------------
// Window_Custom
//
// The window for displaying the party's gold.
function Window_Custom() {
this.initialize(...arguments);
}
Window_Custom.prototype = Object.create(Window_Selectable.prototype);
Window_Custom.prototype.constructor = Window_Custom;
Window_Custom.prototype.initialize = function (rect) {
Window_Selectable.prototype.initialize.call(this, rect);
this.refresh();
};
Window_Custom.prototype.colSpacing = function () {
return 0;
};
Window_Custom.prototype.refresh = function () {
const rect = this.itemLineRect(0);
const x = rect.x;
const y = rect.y;
const width = rect.width;
this.contents.clear();
this.drawText(this.value(), x, y, width, "center");
};
Window_Custom.prototype.value = function () {
return "Hello World";
};
Window_Custom.prototype.open = function () {
this.refresh();
Window_Selectable.prototype.open.call(this);
};
O que fizemos foi pegar todo o código da Window_Gold e modificar algumas partes, nossa janela irá mostrar a mensagem "Hello World". Agora que já temos a janela criada, precisamos adicionar a mesma a camada da Scene que queremos, mas antes iremos entender as Scenes.
O que é uma Scene?
As scenes como o próprio nome já diz são as cenas representadas em tela para o jogador, no RPG MAKER tudo é representado por cenas. Devemos entender a Scene mais importante a "Scene_Base", assim como a "Window_Base" é responsável por cada janela no jogo, a Scene_Base fica responsável por cada cena. Veja o trecho a seguir:
Javascript:
//-----------------------------------------------------------------------------
// Scene_Map
//
// The scene class of the map screen.
const _sceneMap_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function () {
_sceneMap_start.call(this);
this.addWindowCustom(0,0, 200, 100);
};
Scene_Map.prototype.addWindowCustom = function (x, y, width, height) {
this._windowCustom = new Window_Custom(new Rectangle(x, y, width, height));
this.addWindow(this._windowCustom);
};
Perceba que invocamos o método start da cena do map, então toda vez que um mapa for iniciado nossa janela será criada também. Veja a seguinte declaração: const _sceneMap_start = Scene_Map.prototype.start;, o motivo para definir uma o constante com o valor da função que invocamos é que se não fizermos isso, logo a nova declaração adicionada ao método start, iria sobrescrever o anterior e quebrar o jogo, veja o exemplo a seguir:
Javascript:
// Modo errado!
/*
Dessa forma estamos sobrescrevendo o método.
*/
Scene_Map.prototype.start = function() {
Scene_Message.prototype.start.call(this);
SceneManager.clearStack();
this.addWindowCustom(0,0, 200, 100);
};
Scene_Map.prototype.addWindowCustom = function (x, y, width, height) {
this._windowCustom = new Window_Custom(new Rectangle(x, y, width, height));
this.addWindow(this._windowCustom);
};
// Modo correto!
/*
Dessa forma estamos criando um alias (_sceneMap_start) para que o método anterior
ainda possa ser preservado e chamado novamente.
*/
const _sceneMap_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function () {
_sceneMap_start.call(this);
this.addWindowCustom(0,0, 200, 100);
};
Scene_Map.prototype.addWindowCustom = function (x, y, width, height) {
this._windowCustom = new Window_Custom(new Rectangle(x, y, width, height));
this.addWindow(this._windowCustom);
};
Testando nossa Janela!
Agora que já entendemos o que era essencial, vamos criar nossa janela em tela, veja o trecho a seguir:
Javascript:
(function () {
'use strict';
//-----------------------------------------------------------------------------
// Window_Custom
//
// The window for displaying the party's gold.
function Window_Custom() {
this.initialize(...arguments);
}
Window_Custom.prototype = Object.create(Window_Selectable.prototype);
Window_Custom.prototype.constructor = Window_Custom;
Window_Custom.prototype.initialize = function (rect) {
Window_Selectable.prototype.initialize.call(this, rect);
this.refresh();
};
Window_Custom.prototype.colSpacing = function () {
return 0;
};
Window_Custom.prototype.refresh = function () {
const rect = this.itemLineRect(0);
const x = rect.x;
const y = rect.y;
const width = rect.width;
this.contents.clear();
this.drawText(this.value(), x, y, width, "center");
};
Window_Custom.prototype.value = function () {
return "Hello World";
};
Window_Custom.prototype.open = function () {
this.refresh();
Window_Selectable.prototype.open.call(this);
};
//-----------------------------------------------------------------------------
// Scene_Map
//
// The scene class of the map screen.
const _sceneMap_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function () {
_sceneMap_start.call(this);
this.addWindowCustom(0, 0, 200, 100);
};
Scene_Map.prototype.addWindowCustom = function (x, y, width, height) {
this._windowCustom = new Window_Custom(new Rectangle(x, y, width, height));
this.addWindow(this._windowCustom);
};
})();
Abra o seu RPG MAKER e adicione nosso plugin e veja seu funcionamento.
Referências
-
Strict mode - JavaScript | MDN
O strict mode do ECMAScript 5 é uma forma de optar por uma variante restrita do JavaScript. O strict mode não é apenas um subconjunto: ele intencionalmente tem semânticas diferentes do código normal. Navegadores que não suportam strict mode executarão código strict mode com um comportamento...developer.mozilla.org -
JavaScript Function Definitions
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.www.w3schools.com -
Herança em JavaScript - Aprendendo desenvolvimento web | MDN
Com a maior parte dos detalhes principais do OOJS agora explicados, este artigo mostra como criar classes de objetos "child" (construtores) que herdam recursos de suas classes "parent". Além disso, apresentamos alguns conselhos sobre quando e onde você pode usar o OOJS e veja como as classes são...developer.mozilla.org -
JavaScript DOM Navigation
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.www.w3schools.com -
Function.prototype.call() - JavaScript | MDN
O método call() invoca uma função com um dado valor this e argumentos passados individualmente.developer.mozilla.org -
Function.prototype.apply() - JavaScript | MDN
O método apply() chama uma função com um dado valor this e arguments providos como uma array (ou um objeto parecido com um array).developer.mozilla.org -
Function.prototype.bind() - JavaScript | MDN
O método bind() cria uma nova função que, quando chamada, tem sua palavra-chave this definida com o valor fornecido, com uma sequência determinada de argumentos precedendo quaisquer outros que sejam fornecidos quando a nova função é chamada.developer.mozilla.org
Última edição: