1

Donnerstag, 23. März 2017, 02:04

Eigene Plugins erstellen

Hallo Leute,
so ein eigenes Plugin schreiben macht Spaß, man kann damit vor seinen Freunden angeben, sein ganz speziellen Wünsche an den Maker umsetzen und man kann damit vor seinen Freunden angeben. Alles gute Gründe, um sowas mal selber zu machen. In der folgenden Beschreibung wird davon ausgegangen, dass ihr auf einem Microsoft Windows Computer arbeitet und euch meinen lieblings Texteditor installieren könnt. Ich habe aber auch Tipps, wenn ihr gerade an einem Mac oder Linux Computer sitzt.
Wir werden uns ausführlich durch den Entstehungsprozess eines Plugins bewegen und interessante Aspekte oder Dinge die man dafür wissen muss beleuchten. Nach diesem Tutorial solltet ihr in der Lage sein Plugins für RPG Maker MV Games zu entwickeln.

Schauen wir uns mal an, was wir brauchen. Wir brauchen diese drei Dinge:
  1. Wir brauchen etwas, was wir ändern möchten. Zum Beispiel denken wir uns: Hey. Diese Namenseingabe hat mir zuviele unsinnige Zeichen. Die will ich raus haben. Kein Problem. Schreiben wir doch ein Plugin und zeigen es unseren Freunden.

  2. Wir brauchen einen Texteditor, mit dem wir unser Plugin schreiben können. Ich finde es immer ganz schön, wenn man Syntaxhighlighting hat, also dass Schlüsselbegriffe der Programmiersprache hervorgehoben werden. Bunter Programmcode ist besser als monotoner Progammcode. Für die Windows Nutzer empfehle ich da Notepad++ denn der ist gut. Er verwendet intern Scintilla, was auch der Scripteditor der RPG Makern XP bis VX Ace verwendet hat. Alte Hasen fühlen sich darin also vermutlich direkt wie zuhause und neue Hasen gefällt bestimmt das intuitive Design. :download: Notepad++ Download
    Spoiler: :navigation-right: :navigation-left: Alternativen
    Wenn ihr keinen Window Rechner zur Hand habt, dann schreibt euer Plugin doch auf einem Linuxrechner. Nehmt da einfach den Standardeditor mit grafischer Komponente, die können wenn ihr nicht total exotische Distributionen habt alle Syntaxhighlighting. Kein extra Aufwand. Was? Auch kein Linuxrechner zur Hand? Na, dann nehmt doch euren Mac. Ich habe da früher TextWrangler benutzt, der wird aber in Zukunft vom Entwickler eingestellt. Wenn ihr dieses Tutorial in ein paar Jahren erst lest, könnt ihr auf eurem Mac auch Atom installieren. Was? Ihr habt einen Raspberry Pi in euren Toaster eingebaut und wollt darauf euer Plugin schreiben. So hardcore. Aber ja, Leafpad ist dann wohl euer Texteditor. Ja, macht mal und postet hier mal ein Foto von eurem Setup.
    zum Lesen den Text mit der Maus markieren
    :information: Welchen Editor ihr nehmt ist euch überlassen, er muss nur fähig sein, euer Plugin als UTF-8 codierten Text abzuspeichern.

  3. Und abschließend braucht ihr etwas Wissen in JavaScript, der Programmiersprache der Plugins. Es reicht, wenn ihr Basiskenntnisse habt. Die wichtigsten Sachen erkläre ich hier nochmal, aber ihr solltet ein Grundverständniss haben für einen optimalen Lernerfolg. Es wird auch einige Hinweise auf Ähnlichkeiten zum RGSS3 geben, wenn ihr also schonmal für die alten Maker Scripte geschrieben oder angepasst habt wird euch dieses Tutorial hier leichter fallen.


Habt ihr euch Notepad++ installiert oder euch euren bevorzugten Texteditor bereit gelegt? Super! Also dann laufen wir mal los. Schritt für Schritt in Richtung eigenes Plugin.

Schritt 1: Sich die Codestellen raussuchen, die das Plugin verändern soll

Super, dass wir unseren mächtigen Texteditor bereit haben. Der arbeitet jetzt für uns. Geht in den Projektordner eures MV-Projektes. Entweder wählt ihr im Maker im Menü "Spiel -> Spielordner öffnen", oder ihr sucht ihn auf eurem Computer. Vermutlich versteckt er sich im "Eigene Dateien"-Ordner im Unterordner "MV Games". Gefunden? Dann öffnet den Ordner js darin.
Ihr seht jetzt vermutlich die folgenden Ordner und Dateien:
:folder-open: libs, :folder-open: plugins,
:document: main.js, :document: plugin.js, :document: rpg_core.js,
:document: rpg_manager.js, :document: rpg_objects.js, :document: rpg_scenes.js,
:document: rpg_sprites.js, :document: rpg_windows.js


Spoiler: Eine kurze Übersicht, was das ist

  • Der Ordner libs enthält Codebibliotheken für grundsätzliche Funktionen. Für dieses Tutorial uninteressant, aber schaut da gern mal rein. Pixi ist die rendering engine für die MV-Spiele, lz-string dient der Datenkompression, wenn eure Spieler ihren Spielstand speichern und FPSMeter... naja, misst die frames per second.
  • Der Ordner plugins steht soo kurz davor, ein weiteres cooles Plugin zu enthalten. Schnell weiterlesen. Wir stecken da gleich unser Plugin rein.
  • Das Script main.js ist das Äquivalent zum Mainscript in den alten RPG Makern. Wie schon im VX Ace enthält es keine spannenden Definitionen sondern stößt den Spielablauf an. Auch dieses ist uninteressant.
  • Das Script plugin.js wird automatisch vom Maker generiert, immer wenn der Entwickler den PluginManager verwendet. Hier ist nix zu tun. Die Maschine erzeugt dieses Dokument und überschreibt eh immer wieder unsere Änderungen.
  • Das Script rpg_core.js enthält alle grundlegenden Definitionen und Klassen wie das Grafikmodul, das Audiomodul oder die Definition der Tilemap. Sicher spannend, aber sehr unübersichtlich und es erfordert einige fortgeschrittene Kenntnisse, um zu verstehen, was da eigentlich passiert. Vielleicht im nächsten Tutorial. Hier ist aber für deine Plugins in der Regel nichts zu tun.
  • Das Script rpg_manager.js enthält die verschiedenen Manager, die grundlegende Services verwalten. (Das Konzept ist schon aus dem RPG Maker VX Ace bekannt.)
  • Das Script rpg_objects.js enthält die Definition aller Spielelemente, wie die äußere Struktur eines Events, der Spielergruppe oder die Logik eines Battlers.
  • Das Script rpg_scenes.js enthält die Definitionen aller Szenenlogik im Spiel, analog zu der Szenenlogik im RPG Maker VX Ace.
  • Das Script rpg_sprites.js enthält die Definitionen aller Sprites im Spiel, also die Instanzen die sich um die Darstellung einer einzelnen Spielfigur, eines einzelnen Pictures auf der Map oder eines Battlers kümmern. Wenn man in dem Themenfeld etwas sucht, findet man es sehr wahrscheinlich hier.
  • Das Script rpg_windows.js enthält die Definitionen aller Fenster im Spiel, aus jedem Menü, aus dem Kampfsystem, von der Map - alles an einem Ort gesammelt.
zum Lesen den Text mit der Maus markieren

Wir wollen mit unserem Plugin ein Fenster verändern, also schauen wir in die rpg_windows.js. Öffnet sie mit Notepad++ oder dem Editor, den ihr für euch gewählt habt. Okay, Sechstausendeinundzwanzig Zeilen an Code. Nicht erschrecken, das ist für uns kein Problem. Erstens ist der Code bunt (Danke Syntaxhighlighting) und zweitens unterstützt der Texteditor uns mit einer Suchfunktion. Im RPG Maker MV sind alle Fensterklassen recht sprechend benannt. Suchen (Strg+F) wir also mal nach Window_Name und Zack! Window_NameEdit gefunden:

JavaScript Quellcode

3410
3411
3412
3413
//-----------------------------------------------------------------------------
// Window_NameEdit
//
// The window for editing an actor's name on the name input screen.
Das ging doch superschnell. Wenn wir weiterscrollen sehen wir aber - hm, da ist ja garkeine Auflistung der Buchstaben. Tatsächlich ist Window_NameEdit nicht das untere Fenster, sondern das obere Fenster im Namenseingabe-Bildschirm. Aber direkt darunter finden wir Window_NameInput und da stehen ja auch unsere Zeichentabellen, klasse!
Spoiler: Quellcodeausschnitt

JavaScript Quellcode

3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
//-----------------------------------------------------------------------------
// Window_NameInput
//
// The window for selecting text characters on the name input screen.
 
function Window_NameInput() {
    this.initialize.apply(this, arguments);
}
 
Window_NameInput.prototype = Object.create(Window_Selectable.prototype);
Window_NameInput.prototype.constructor = Window_NameInput;
Window_NameInput.LATIN1 =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','[',']','^','_',  'z','{','}','|','~',
          '0','1','2','3','4',  '!','#','$','%','&',
          '5','6','7','8','9',  '(',')','*','+','-',
          '/','=','@','<','>',  ':',';',' ','Page','OK' ];
Window_NameInput.LATIN2 =
        [ 'Á','É','Í','Ó','Ú',  'á','é','í','ó','ú',
          'À','È','Ì','Ò','Ù',  'à','è','ì','ò','ù',
          'Â','Ê','Î','Ô','Û',  'â','ê','î','ô','û',
          'Ä','Ë','Ï','Ö','Ü',  'ä','ë','ï','ö','ü',
          'Ā','Ē','Ī','Ō','Ū',  'ā','ē','ī','ō','ū',
          'Ã','Å','Æ','Ç','Ð',  'ã','å','æ','ç','ð',
          'Ñ','Õ','Ø','Š','Ŵ',  'ñ','õ','ø','š','ŵ',
          'Ý','Ŷ','Ÿ','Ž','Þ',  'ý','ÿ','ŷ','ž','þ',
          'IJ','Œ','ij','œ','ß',  '«','»',' ','Page','OK' ];

JavaScript Quellcode

3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
Window_NameInput.prototype.windowHeight = function() {
    return this.fittingHeight(9);
};
 
Window_NameInput.prototype.table = function() {
    if ($gameSystem.isJapanese()) {
        return [Window_NameInput.JAPAN1,
                Window_NameInput.JAPAN2,
                Window_NameInput.JAPAN3];
    } else if ($gameSystem.isRussian()) {
        return [Window_NameInput.RUSSIA];
    } else {
        return [Window_NameInput.LATIN1,
                Window_NameInput.LATIN2];
    }
};
 
Window_NameInput.prototype.maxCols = function() {
    return 10;
};
 
Window_NameInput.prototype.maxItems = function() {
    return 90;
};
 
Window_NameInput.prototype.character = function() {
    return this._index < 88 ? this.table()[this._page][this._index] : '';
};
 
Window_NameInput.prototype.isPageChange = function() {
    return this._index === 88;
};
 
Window_NameInput.prototype.isOk = function() {
    return this._index === 89;
};
zum Lesen den Text mit der Maus markieren

Okay. Soweit sehr gut: Wir haben die Quelle unseres Ärgers gefunden. Jetzt müssen wir uns klar werden, was wir wollen. Im Rahmen dieses Tutorials wollen wir das es nur eine Seite gibt und wir möchten dort andere Zeichen haben. Merken: Wir definieren also eine neue Zeichentabelle in unserem Plugin. Aus dieser Änderung folgt, dass wir das Fenster also auch nicht so groß brauchen, wir streichen ein paar Zeilen weg. Um es jetzt nicht zu kompliziert zu machen, behalten wir das zweispaltige Layout aber bei. Merke: Wir setzen in unserem Plugin eine neue (etwas geringere) Höhe für unser NameInput-Fenster. Wir müssen auch noch ein paar Sachen zusätzlich hier anpassen, aber darauf kommen wir gleich nochmal zurück. Beginnen wir jetzt erstmal unser Plugin zu schreiben.

Schritt 2: Ein neues Plugin erstellen: Editor vorbereiten


Geht in Notepad++ im Menü auf "Datei -> Neu" oder klickt einfach auf den kleinen "Neues Dokument"-Icon, ganz links in der Menüzeile. Wählt dann in der Menüzeile den Punkt "Sprache" aus und dort bei "J" als Sprache "JavaScript". Jetzt habt ihr hübsche Zeilennummern und ein Syntaxhighlighting für JavaScript-Schlüsselbegriffe. Wählt jetzt noch im Menü den Punkt "Kodierung" und schaltet die Kodierung um auf "UTF-8 ohne BOM" (ohne Byteorder-Markierung). Wir sind soweit vorbereitet. Schreiben wir ein Plugin.
Das kleinste Plugin (was dann nichts tut) sieht so aus:

JavaScript Quellcode

1
2
3
(function() {
 
})();

Es besteht aus einer leeren immediate function. Was ist das? Naja, vor allem Englisch. Man kann das wörtlich als "unmittelbare Funktion" übersetzen, eine Funktion, die direkt bei ihrer Defintion auch ausgeführt wird. Hier mal kurz die Syntax aufgeschlüsselt:
  • (function() {

    }
    )();

Wir definieren eine normale Funktion, ohne Namen.

  • (function() {

    }
    )();

Dann nehmen wir uns diese Funktion, die wir eben definiert haben.

  • (function() {

    })
    ();

Und führen sie direkt aus. Wow, wie praktisch.

Tatsächlich ist das sehr beruhigend und Teil der Pluginspezifikation, dass der arbeitende Code eines Plugins in so eine immediate function gehüllt werden muss. Tut ihr dies, könnt ihr euch sicher sein, dass ihr nicht ausversehen wichtige Funktionen überschreibt oder mit dem Code anderer Pluginentwickler sich ins Gehege kommt, da all eure Variablendeklarationen, die ihr in die geschweiften Klammern der immediate function geschrieben habt, danach verschwinden. Ein gutes Beispiel lernen wir nachher kennen, wenn wir das Window_NameInput erweitern.

Schritt 3: Ein neues Plugin erstellen: Jetzt schreiben wir Code!


Wir wollen unsere eigene Zeichentabelle erstellen. Weil wir effizient sind (lies: faul) kopieren wir dafür die LATIN1-Zeichentabelle aus dem rpg_windows.js zu uns rüber. Wenn ihr Notepad++ benutzt und die Datei von eben noch offen habt könnt ihr über die Tabs oben im Fenster auf die rpg_windows.js wechseln (ansonsten öffnet ihr sie halt nochmal fix). Unser Plugin sieht dann bisher so aus:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function(){
 
Window_NameInput.LATIN1 =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','[',']','^','_',  'z','{','}','|','~',
          '0','1','2','3','4',  '!','#','$','%','&',
          '5','6','7','8','9',  '(',')','*','+','-',
          '/','=','@','<','>',  ':',';',' ','Page','OK' ];
 
})();

Wir geben der Zeichentabelle jetzt erstmal einen neuen Namen:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','[',']','^','_',  'z','{','}','|','~',
          '0','1','2','3','4',  '!','#','$','%','&',
          '5','6','7','8','9',  '(',')','*','+','-',
          '/','=','@','<','>',  ':',';',' ','Page','OK' ];
 
})();

Sehr schön. Passt auf, dass ihr für das bestehende Window_NameInput ein neues Attribut "SimpleTable" definiert habt. Ändert nur den Attributnamen, aber nicht den Namen links vom Punkt. Und jetzt ändern wir den Table noch dahingehend, dass er wirklich etwas einfacher ist. Ich lösche dafür die letzten drei Zeilen raus und passe die dann letzte Zeile etwas an. Nicht vergessen den Bestätigen-Knopf wieder einzufügen:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','Ä','Ö','Ü',' ',  'z','ä','ö','ü','OK' ];
 
})();


Soweit so gut. Jetzt möchten wir natürlich noch, dass die Namenseingabe auch unsere Zeichentabelle benutzt und nicht die unter LATIN1 definierte. Dafür ändern wir jetzt eine Funktion der Klasse Window_NameInput ab. Ich zeig euch, wie es geht.

Die Funktion table wählt für das Fenster die passende Zeichentabelle aus. Wir möchten jetzt aber, dass in bestimmten Situationen unsere Zeichentabelle benutzt wird.

JavaScript Quellcode

3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
Window_NameInput.prototype.table = function() {
    if ($gameSystem.isJapanese()) {
        return [Window_NameInput.JAPAN1,
                Window_NameInput.JAPAN2,
                Window_NameInput.JAPAN3];
    } else if ($gameSystem.isRussian()) {
        return [Window_NameInput.RUSSIA];
    } else {
        return [Window_NameInput.LATIN1,
                Window_NameInput.LATIN2];
    }
};

Nehmen wir uns kurz den Moment zu überlegen, was wir ändern möchten: Sagen wir mal, wenn ein Switch auf AN steht, soll unsere SimpleTable verwendet werden, ansonsten soll er halt eine passende Zeichentabelle auswählen, also das machen, was er auch sonst machen würde. Das Stichwort hier für die Rubyprogrammier des RMXP bis RMVXace heißt Aliasen. Und das machen wir jetzt in unserem Plugin.
Schreiben wir mal die Funktion table neu, sodass wenn der Switch mit der Nummer 52 an ist, er unsere Zeichentabelle benutzt:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','Ä','Ö','Ü',' ',  'z','ä','ö','ü','OK' ];
 
Window_NameInput.prototype.table = function() {
    if ( $gameSwitches.value(52) ) {
        return [Window_NameInput.SimpleTable];
    }
};
 
})();

Das Problem hier wäre, dass wir so die originale Methode überschreiben und die originale Definition verlieren. Wie schade und inkompatibel. Als guter Pluginentwickler (wir sind natürlich sehr gut) wollen wir schön kompatible Plugins bauen, die all unsere Freunde sofort benutzen wollen.
Zum Glück sind in JavaScript Funktionen sogenannte Function-Objekte. Wir haben ja schon gesehen, dass man sie einfach so in Attribute speichern kann: Schaut hin, das definieren der table Funktion der Klasse Window_NameInput ist ja auch nur ein "Ich speichere mir diese Funktion in dieses Attribut mit dem Namen table". Wir können also uns die alte Definition der Funktion einfach in einer Variable merken und verlieren sie so nicht beim Neudefinieren.
Schauen wir uns das mal als Code an. Besonderes Augenmerk auf Zeile 11:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','Ä','Ö','Ü',' ',  'z','ä','ö','ü','OK' ];
 
var _Window_NameInput_table = Window_NameInput.prototype.table;
 
Window_NameInput.prototype.table = function() {
    if ( $gameSwitches.value(52) ) {
        return [Window_NameInput.SimpleTable];
    }else{
	return _Window_NameInput_table.call(this);
    }
};
 
})();


Wir haben uns die originale Definition in der lokalen Variable _Window_NameInput_table gemerkt. Durch die Zauberhaftigkeit von JavaScript, können wir die so gemerkte originale Definition dann sogar in unserer neuen Definition der Methode verwenden, siehe Zeile 17. Wir nehmen einfach die Variable her und "callen" das darin gespeicherte Function-Objekt. Dabei übergeben wir einmal this und danach alle Parameter, die die Funktion sonst auch hätte. Da table aber keine Parameter hat, bekommt der call nach dem this auch keine weiteren Parameter. Man kann das jetzt so hinnehmen, dass das so geht, oder sich weiterbilden und zum Beispiel den Artikel im Mozilla Developer Network zu call lesen.

Wer das Alias noch aus RGSS-Zeiten kennt, mag jetzt die Frage stellen: Hey, ist es nicht besser für die Variable _Window_NameInput_table einen etwas individuelleren Namen zu nehmen? Was ist, wenn ein anderer Pluginentwickler den gleichen Namen hat? Nun, das ist egal. Diese Variable, die wir hier benutzen steht in einer immediate function und verschwindet nachdem wir unsere Methode definiert haben wieder. Es kommt also niemals zu einer Kollision mit anderen Pluginentwicklern und wir müssen uns keine seltsamen Namen ausdenken. Mit JavaScript und immediate functions geht das.

So, genug an diesem einen Teilschritt begeistert - wir haben noch ein bisschen zu tun. Unser NameInput-Fenster ist jetzt unnötig hoch nachdem wir drei Zeilen rausgenommen haben. Also machen wir jetzt das gleiche wie eben nochmal für die Methode windowHeight:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','Ä','Ö','Ü',' ',  'z','ä','ö','ü','OK' ];
 
var _Window_NameInput_table = Window_NameInput.prototype.table;
 
Window_NameInput.prototype.table = function() {
    if ( $gameSwitches.value(52) ) {
        return [Window_NameInput.SimpleTable];
    }else{
	return _Window_NameInput_table.call(this);
    }
};
 
var _Window_NameInput_windowHeight = Window_NameInput.prototype.windowHeight;
 
Window_NameInput.prototype.windowHeight = function() {
    if ( $gameSwitches.value(52) ) {
        return this.fittingHeight(6);
    }else{
	return _Window_NameInput_windowHeight.call(this);
    }
};
 
})();


Und das ist das ganze Redefining Methods-Prinzip. Damit können wir jetzt weitermachen und das Plugin weiter verfeinern: Der Bestätigen-Knopf sitzt in unserer Zeichentabelle nichtmehr auf Index 89, sondern da wir weniger Zeichen in unserer Tabelle haben, sitzt er jetzt auf Index 59. Das können wir anpassen! Wir wenden das gleiche Prinzip wie oben nochmal an: Alte Funktion in eine lokale Variable. Funktion neudefinieren. Das sieht dann so aus:

JavaScript Quellcode

31
32
33
34
35
36
37
38
39
var _Window_NameInput_isOk = Window_NameInput.prototype.isOk;
 
Window_NameInput.prototype.isOk = function() {
    if ( $gameSwitches.value(52) ) {
        return this._index === 59;
    }else{
	return _Window_NameInput_isOk.call(this);
    }
};


Wir können einfach durch die Funktion der Klasse Window_NameInput in der rpg_windows.js scrollen und gucken, was unser Plugin für seine neue Zeichentabelle anpassen muss. Das ist auch immer der Fall, wenn die Anzahl der Zeichen referenziert wird (90, 90-1 oder 90-2), die wir dann auf 60, 60-1 oder 60-2 korrigieren. Unser Plugin sieht dann erstmal so aus:
Spoiler: Aktueller Stand des Plugins

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
(function(){
 
Window_NameInput.SimpleTable =
        [ 'A','B','C','D','E',  'a','b','c','d','e',
          'F','G','H','I','J',  'f','g','h','i','j',
          'K','L','M','N','O',  'k','l','m','n','o',
          'P','Q','R','S','T',  'p','q','r','s','t',
          'U','V','W','X','Y',  'u','v','w','x','y',
          'Z','Ä','Ö','Ü',' ',  'z','ä','ö','ü','OK' ];
 
var _Window_NameInput_table = Window_NameInput.prototype.table;
 
Window_NameInput.prototype.table = function() {
    if ( $gameSwitches.value(52) ) {
        return [Window_NameInput.SimpleTable];
    }else{
	return _Window_NameInput_table.call(this);
    }
};
 
var _Window_NameInput_windowHeight = Window_NameInput.prototype.windowHeight;
 
Window_NameInput.prototype.windowHeight = function() {
    if ( $gameSwitches.value(52) ) {
        return this.fittingHeight(6);
    }else{
	return _Window_NameInput_windowHeight.call(this);
    }
};
 
var _Window_NameInput_isOk = Window_NameInput.prototype.isOk;
 
Window_NameInput.prototype.isOk = function() {
    if ( $gameSwitches.value(52) ) {
        return this._index === 59;
    }else{
	return _Window_NameInput_isOk.call(this);
    }
};
 
var _Window_NameInput_maxItems = Window_NameInput.prototype.maxItems;
 
Window_NameInput.prototype.maxItems = function() {
    if ( $gameSwitches.value(52) ) {
        return 60;
    }else{
	return _Window_NameInput_maxItems.call(this);
    }
};
 
var _Window_NameInput_character = Window_NameInput.prototype.character;
 
Window_NameInput.prototype.character = function() {
    if ( $gameSwitches.value(52) ) {
        return this._index < 59 ? this.table()[this._page][this._index] : '';
    }else{
	return _Window_NameInput_character.call(this);
    }
};
 
var _Window_NameInput_cursorDown = Window_NameInput.prototype.cursorDown;
 
Window_NameInput.prototype.cursorDown = function(wrap) {
    if ( $gameSwitches.value(52) ) {
        if (this._index < 60 || wrap) {
		this._index = (this._index + 10) % 60;
	}
    }else{
	return _Window_NameInput_cursorDown.call(this, wrap);
    }
};
 
var _Window_NameInput_cursorUp = Window_NameInput.prototype.cursorUp;
 
Window_NameInput.prototype.cursorUp = function(wrap) {
    if ( $gameSwitches.value(52) ) {
        if (this._index >= 10 || wrap) {
            this._index = (this._index + 50) % 60;
	}
    }else{
        return _Window_NameInput_cursorUp.call(this, wrap);
    }
};
 
var _Window_NameInput_processJump = Window_NameInput.prototype.processJump;
 
Window_NameInput.prototype.processJump = function() {
    if ( $gameSwitches.value(52) ) {
        if (this._index !== 59) {
            this._index = 59;
            SoundManager.playCursor();
	}
    }else{
        return _Window_NameInput_processJump.call(this);
    }
};
 
})();
zum Lesen den Text mit der Maus markieren


Das ist für den Moment schonmal super. Das Plugin würde jetzt schon funktionieren. Probieren wir es doch im nächsten Schritt mal aus, dem neuen Plugin einen Namen zu geben und es im Maker zu verwenden.

Schritt 4: Das Plugin im Maker verwenden


Den Dateinamen den ihr eurem Plugin gebt (ohne die Dateiendung ".js") wird auch im Maker als Pluginname angezeigt. Am Besten ist er einzigartig mit Wiedererkennungswert; dafür schreiben viele Pluginentwickler einfach ihren Namen rein. Macht das ruhig auch, dass euer Plugin dann zum Beispiel Gast_SimplerNameInput.js heißt. Bisher sind mir aber keine Restriktionen für den Pluginnamen bekannt, also seid da beliebig kreativ. Sollange es ein valider Dateiname/eine valide URL ist, passt das schon.

Habt ihr euer geschriebenes Plugin jetzt mit der Dateiendung ".js" in den Pluginordner eures Projekts gespeichert? Prima. Dann schaut doch mal im Maker, ob ihr das Plugin aktivieren könnt. Der PluginManager sieht noch ein bisschen leer aus - im nächsten Schritt werden wir auch noch die ganzen Informationen wie Autor, Beschreibung und Hilfetext ins Plugin einpflegen (ein Plugin ist gleich doppelt gut, wenn euer eigener Name/Nick als Autor auftaucht). Aber wir können das Plugin schon testen und wenn der Switch 52 eingeschaltet ist, kommt auch tatsächlich unsere hübsche, kleine Zeichentabelle zum Einsatz. Supi. Dann können wir jetzt unser Plugin durch das Einfügen einer Beschreibung und Autoreninformationen auf eine professionellere Ebene heben. (Und je professioneller euer Plugin aussieht, desto mehr könnt ihr damit vor euren Freunden prahlen. Reiner Gewinn!)

Schritt 5: Plugin-Beschreibung, Autoreninformationen und erweiterte Hilfetexte



Diese Informationen fügt ihr in eure eben abgespeicherte Plugindatei ein, indem ihr mindestens den folgenden Text einfügt:

JavaScript Quellcode

1
2
3
/*:
 * 
 */

Das ist schon eine valide Angabe von Informationen, aber leider habt ihr alle möglichen Informationen ausgelassen. Vielleicht reichern wir das noch etwas an:

JavaScript Quellcode

1
2
3
/*:
 * @author Playm
 */

Nicht schlecht. In den ersten drei Zeilen eures Plugins haben wir jetzt die Information der Autorenschaft hinterlegt. Danach kommt unsere immediate function wie gehabt:

JavaScript Quellcode

1
2
3
4
5
6
7
/*:
 * @author Playm
 */
(function(){
 
Window_NameInput.SimpleTable =
   ...


Wenn ihr die Änderungen in eurer Gast_SimplerNameInput.js Datei abgespeichert habt und im Maker den PluginManager öffnet seht ihr schonmal euren Namen (oder "Playm", wenn ihr hier wirklich 1:1 abschreibt) als Autor stehen. Das reicht uns aber nicht. Wir wollen auch das Beschreibungsfeld füllen. Ich zeig euch wie es geht:

JavaScript Quellcode

1
2
3
4
5
/*:
 * @plugindesc Verwendet für die Namenseingabe eine kleinere Zeichenauswahl
 * 
 * @author Playm
 */

Tada! :thank_you: Schon haben wir auch diese Information im Plugin drinnen. Jetzt sieht es schon ziemlich gut aus.
Aber wenn wir auf "Hilfe" klicken im PluginManager erscheint immernoch ein leeres Fenster. Da kann man auch noch was reinschreiben und zwar so:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
/*:
 * @plugindesc Verwendet für die Namenseingabe eine kleinere Zeichenauswahl
 * 
 * @author Playm
 *
 * @help
 * Schalte in deinem Spiel den Switch 52 EIN, um beim Eventbefehl Namenseingabe
 * eine kleinere Zeichenauswahl die nur aus dem deutschen Alphabet besteht zur
 * Verfügung zu haben.
 */

Ziemlich einfach nicht? Das hat man sich als Pluginentwickler schnell gemerkt und ansonsten setzt euch doch ein Lesezeichen für dieses Tutorial. :addressbook:
Wir haben jetzt alles auf deutsch reingeschrieben, aber da ihr bald weltweit als bester Pluginentwickler bekannt seien werdet, werden auch Spieleentwickler euer Plugin verwenden, die kein Deutsch können. Für die können wir auch was tun, ohne mehrere Plugindateien anbieten zu müssen. Lest einfach den nächsten Schritt.

Schritt 6: Plugin-Beschreibung in mehreren Sprachen anbieten


Der Maker unterstützt aktuell die Sprachen Japanisch, Französisch, Deutsch, Spanisch, Italienisch, Portugiesisch, Russisch, Chinesisch und Koreanisch und für andere Regionen Englisch.
Ihr könnt für jede Sprache eine eigene Pluginbeschreibung definieren. Spielentwickler, die ihren Maker dann auf zum Beispiel "Deutsch" gestellt haben, kriegen die deutsche Beschreibung und ein Italiener oder Koreaner kann eine von euch definierte "default" Beschreibung in englischer Sprache bekommen. International die Menschen glücklich machend - das wird man denken wenn man den Namen Gast hört. Großartig.

Um dies zu erreichen fügt ihr mehrere comment blocks ein:

JavaScript Quellcode

1
2
3
4
5
6
7
/*:
 * 
 */
 
/*:
 * 
 */


Für jede Sprache gibt es ein Sprachkürzel: Japanisch=ja, Französisch=fr, Deutsch=de, Spanisch=es, Italienisch=it, Portugiesisch=pt, Russisch=ru, Chinesisch=zh und Koreanisch=ko. Um dem Maker zu signalisieren, dass die Informationen im Block für eine bestimmte Sprache sind, setzt ihr hinter das /*: das Sprachkürzel. Das könnte für unser Plugin dann so aussehen:

JavaScript Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*:de
 * @plugindesc Verwendet für die Namenseingabe eine kleinere Zeichenauswahl
 * 
 * @author Playm
 *
 * @help
 * Schalte in deinem Spiel den Switch 52 EIN, um beim Eventbefehl Namenseingabe
 * eine kleinere Zeichenauswahl die nur aus dem deutschen Alphabet besteht zur
 * Verfügung zu haben.
 */
 /*:
 * @plugindesc Use a smaller character set for NameInput Eventcommand
 * 
 * @author Playm
 *
 * @help
 * Activate Switch 52 in your game, to use the smaller character set for name
 * input. This characer set only support the Letters A-Z, a-z and the german
 * Ä, Ö and Ü.
 */

Wie ihr seht habe ich für die deutschsprachigen Spielentwickler Informationen in deutscher Sprache hinterlegt und für alle anderen (kein Sprachkürzel angeben, also default Infos) habe ich mit meinem Englischwörterbuch noch eine internationale Version der Informationen hinterlegt. Und das könnt ihr auch. Schreibt doch euer Plugin so, dass man es auf der ganzen Welt in Spiele einbauen kann.
Soweit sind wir mit dem Plugin fertig. Im siebten und letzten Schritt, möchten wir unser Plugin noch um Parameter erweitern. Wir haben jetzt hard gecoded, dass es immer Switch Nummer 52 seien muss. Das war vielleicht nicht so klug. Das korrigieren wir im nächsten Schritt, sodass der Pluginbenutzer angeben kann, welchen Switch er benutzen möchte.

Schritt 7: Eigene Plugin-Parameter


ToDo... :hourglass:
Dieser Abschnitt ist noch nicht fertig. Schau doch nochmal am Samstag rein, dann dürftest Du hier noch eine ausführliche Beschreibung finden.

Schlusswort


Unser Plugin ist fertig. Kleinschrittig haben wir uns durch die komplette Entwicklung eines Plugins gehangelt und hoffentlich alle wichtigen Aspekte angesprochen. Wir haben noch nicht alle Themen der Pluginentwicklung abgedeckt, man könnte noch einiges mehr sagen aber das passiert dann in einem neuen Tutorial. Eure Fragen dazu, eure Anregungen und was ihr vielleicht unklar fandet: Schreibt es hier in den Thread. Und jetzt viel Spaß bei eurer eigenen Entwicklung von Plugins.

Ähnliche Themen

Social Bookmarks