Hallo,
ich möchte gerne ein kleines Framework vorstellen, was ich zuerst für den eigenen Bedarf auf einem Server entwickelt habe und jetzt gerne öffentlich teilen möchte.
Es handelt sich um ein Tool für das Erstellen von Scoreboards, Bossbars und Menüs in Spielerinventaren sowie "Top" Inventaren (Chest, Anvil, Furnace, ...).
Es ist die erste Resource, die ich öffentich vorstelle und ich freue mich sehr über Kritik und Feedback!
Vorab: Das Framework ist bisher in der Startphase mit v0.1.0 und es können sich jederzeit Features ändern. Es ist entwickelt und getestet mit Spigot 1.18.2, Java 17 und benötigt die Adventure Component API, die neuerdings in Paper enthalten ist.
Repository: https://github.com/CubBossa/Minecraft-GUI-Framework
Scoreboards und Bossbars nehmen einen kleinen Teil ein und sind vorallem der Vollständigkeit halber dabei, da es ja ein GUI Framework ist und kein Menu Framework.
Die Menüs sind aufgeteilt in die Menüs im unteren Spielerinventar und die Menüs in den oberen Inventaren. Dabei sind TopInventoryMenus so aufgebaut, dass sie eine Stack-artige Struktur verfolgen können und man leicht verschachtelte Untermenüs aufbauen kann. Schließt man ein Untermenü, öffnet sich das Parent Menü.
Menüs im Spielerinventar können sich dagegen überschneiden, da jedes mit einem Slot Array initialisiert wird. Sie sind zwar auch Stack-artig angeordnet, es können aber jederzeit beliebig viele Spielerinventar-Menüs geöffnet sein und sie liegen wie ein Stapel aus zurecht geschnittenem Papier übereinander, so dass eben vom obersten Menü am meisten zu sehen ist. Sie unterstützen, sofern die Slots in der Hotbar liegen, auch Aktionen wie das Klicken von Blöcken und Entities. Aktionen können durch neue Listener beliebig hinzugefügt werden.
Hier wäre ein kleines Beispiel für ein Menü, um alle Spieler aufzulisten und sich mit Linksklick zu einem zu teleportieren:
Man kann in jedem Menü auf jeden beliebigen Slot im Integer-Wertebereich Items legen. Ist der Slot-Index außerhalb der Inventarslots, liegt das Item auf einer höheren oder niedrigeren Seite. Mit dem Seitenattribut beim Öffnen lässt sich ein bestimmter Abschnitt der Slot-Map rendern.
Um bestimmte Funktionen auf jeder Seite umzusetzen die selbst Items besitzt, gibt es sogenannte MenuPresets. Diese sind Objekte, die nach dem Befüllen des Inventars auf alle freien Slots eine Aktion ausführen können, beispielsweise alle leeren Slots der aktuellen Seite mit grauen Glasscheiben füllen. Diese Aktion ist nicht permanent, das Preset wird vor jedem Rendern neu auf die Seite angewandt. Es ist also genau das passende Werkzeug um zum Beispiel Buttons zum Seiten umblättern zu implementieren, welche standardmäßig nicht gesetzt werden.
Damit man diese nicht selbst definieren muss, habe ich ein paar statische Methoden zur Erzeugung von Pagination Presets in der Klasse MenuPresets angelegt.
ListMenus bieten zusätzlich die Möglichkeit, Objekte an eine Liste anzuhängen und die Verwaltung der Slot Belegung dem Menü zu überlassen. Habe ich beispielsweise eine Liste aller aktiven Spieler und möchte sie im Join und Quit event aktuallisieren, kann ich die refresh Methode auf alle Listenslots aufrufen und das ListMenu wird automatisch die Köpfe an die rechte Stelle rücken.
AnvilMenus sind ein Wrapper um die bekannte AnvilGUI API, die ich gerne verwende, die sich aber bisher nicht in das Menü Schema gefügt hat. Die AnvilMenu Klasse benutzt die Methodenaufrufe der AnvilGUI Klasse, kann aber als Untermenü anderer Menüs geöffnet werden und eigene Submenüs besitzen.
Noch geplant:
Ich freue mich wie gesagt auf Feedback und Tipps zur Veröffentlichung von solchem Code. Auch bei der Benennung freue ich mich über Inspiration, ich würde gerne noch einen Namen finden, der sich besser abkürzen lässt und nicht so sperrig ist.
Liebe Grüße, Leo
ich möchte gerne ein kleines Framework vorstellen, was ich zuerst für den eigenen Bedarf auf einem Server entwickelt habe und jetzt gerne öffentlich teilen möchte.
Es handelt sich um ein Tool für das Erstellen von Scoreboards, Bossbars und Menüs in Spielerinventaren sowie "Top" Inventaren (Chest, Anvil, Furnace, ...).
Es ist die erste Resource, die ich öffentich vorstelle und ich freue mich sehr über Kritik und Feedback!
Vorab: Das Framework ist bisher in der Startphase mit v0.1.0 und es können sich jederzeit Features ändern. Es ist entwickelt und getestet mit Spigot 1.18.2, Java 17 und benötigt die Adventure Component API, die neuerdings in Paper enthalten ist.
Repository: https://github.com/CubBossa/Minecraft-GUI-Framework
Scoreboards und Bossbars nehmen einen kleinen Teil ein und sind vorallem der Vollständigkeit halber dabei, da es ja ein GUI Framework ist und kein Menu Framework.
Die Menüs sind aufgeteilt in die Menüs im unteren Spielerinventar und die Menüs in den oberen Inventaren. Dabei sind TopInventoryMenus so aufgebaut, dass sie eine Stack-artige Struktur verfolgen können und man leicht verschachtelte Untermenüs aufbauen kann. Schließt man ein Untermenü, öffnet sich das Parent Menü.
Menüs im Spielerinventar können sich dagegen überschneiden, da jedes mit einem Slot Array initialisiert wird. Sie sind zwar auch Stack-artig angeordnet, es können aber jederzeit beliebig viele Spielerinventar-Menüs geöffnet sein und sie liegen wie ein Stapel aus zurecht geschnittenem Papier übereinander, so dass eben vom obersten Menü am meisten zu sehen ist. Sie unterstützen, sofern die Slots in der Hotbar liegen, auch Aktionen wie das Klicken von Blöcken und Entities. Aktionen können durch neue Listener beliebig hinzugefügt werden.
Hier wäre ein kleines Beispiel für ein Menü, um alle Spieler aufzulisten und sich mit Linksklick zu einem zu teleportieren:
Beispiel:
Player player = (Player) commandSender;
ListMenu menu = new ListMenu(3, Component.text("Zu Spieler teleportieren:"));
// Patination Preset laden
menu.addPreset(MenuPresets.paginationRow(3, 0, 1, false, Action.LEFT))
// Spielerköpfe mit Funktion hinzufügen
for (Player target : Bukkit.getOnlinePlayers()) {
menu.addListEntry(ButtonBuilder.buttonBuilder()
.withItemStack(ItemStackUtils.createCustomHead(target))
.withClickHandler(Action.LEFT, clickContext -> {
player.teleport(target);
}));
}
menu.open(player);
Man kann in jedem Menü auf jeden beliebigen Slot im Integer-Wertebereich Items legen. Ist der Slot-Index außerhalb der Inventarslots, liegt das Item auf einer höheren oder niedrigeren Seite. Mit dem Seitenattribut beim Öffnen lässt sich ein bestimmter Abschnitt der Slot-Map rendern.
Um bestimmte Funktionen auf jeder Seite umzusetzen die selbst Items besitzt, gibt es sogenannte MenuPresets. Diese sind Objekte, die nach dem Befüllen des Inventars auf alle freien Slots eine Aktion ausführen können, beispielsweise alle leeren Slots der aktuellen Seite mit grauen Glasscheiben füllen. Diese Aktion ist nicht permanent, das Preset wird vor jedem Rendern neu auf die Seite angewandt. Es ist also genau das passende Werkzeug um zum Beispiel Buttons zum Seiten umblättern zu implementieren, welche standardmäßig nicht gesetzt werden.
Damit man diese nicht selbst definieren muss, habe ich ein paar statische Methoden zur Erzeugung von Pagination Presets in der Klasse MenuPresets angelegt.
ListMenus bieten zusätzlich die Möglichkeit, Objekte an eine Liste anzuhängen und die Verwaltung der Slot Belegung dem Menü zu überlassen. Habe ich beispielsweise eine Liste aller aktiven Spieler und möchte sie im Join und Quit event aktuallisieren, kann ich die refresh Methode auf alle Listenslots aufrufen und das ListMenu wird automatisch die Köpfe an die rechte Stelle rücken.
AnvilMenus sind ein Wrapper um die bekannte AnvilGUI API, die ich gerne verwende, die sich aber bisher nicht in das Menü Schema gefügt hat. Die AnvilMenu Klasse benutzt die Methodenaufrufe der AnvilGUI Klasse, kann aber als Untermenü anderer Menüs geöffnet werden und eigene Submenüs besitzen.
Noch geplant:
- Ein Villager GUI
- Evtl. eine Aktion für die Eingabe in das Anvil Textfeld, was allerdings zusätzlich Protocollib erfordern würde
- Evtl. ein Offset Wert, der die Variable für die aktuelle Seite ablöst. So könnte man durch das Inventar scrollen, in dem man den Offset-Wert nur um 9 erhöht.
- Evtl. ItemStacks ablösen durch Supplier<ItemStack>s, damit man Animationen und Input Feedback direkt in die Items legen kann und nurnoch die Refresh-Methode für betroffene Slots aufrufen muss.
Ich freue mich wie gesagt auf Feedback und Tipps zur Veröffentlichung von solchem Code. Auch bei der Benennung freue ich mich über Inspiration, ich würde gerne noch einen Namen finden, der sich besser abkürzen lässt und nicht so sperrig ist.
Liebe Grüße, Leo