• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Bewegende Items in GUI programmieren

Michelus

Minecrafter
Registriert
5 März 2020
Beiträge
6
Diamanten
300
Hallo liebe Community dank eurer Hilfe konnte ich meine letzte frage gut umsetzen.

nun habe ich eine neue, ich möchte eine GUI programmieren in der sich Graue Glascheiben befinden und von links nach rechts durch grüne ersetzt werden. Ich habe schon angefangen zu coden aber es klappt nicht so ganz. Entweder ist das Inv voller grauer oder grüner Scheiben.

Vielen dank für eure Hilfe, im Anhang befindet sich ein Bild wie das ganze aussehen soll. (Die Gelben Scheiben bewegen sich von links nach rechts)

Der Link zum Code: https://pastebin.com/tMVTdWAk
 

Anhänge

  • Ladebalken.png
    Ladebalken.png
    3,1 KB · Aufrufe: 269

Vestri

Minecrafter
Registriert
30 März 2012
Beiträge
8
Alter
36
Diamanten
252
Minecraft
Vestri
Hey,

dein Problem ist, wenn du deinen Task das erste mal ausführst, ersetzt du durch die Iteration sofort alle Elemente auf einmal und brichst danach sofort wieder den Task ab.

Du könnest z.B etwas einbauen was schaut welche Postion schon Grün ist und einfach nur die nächst höhere ersetzt. Wenn dann die max Inventar Länge erreicht beendest du den Task.

Zusätzlich solltest du das ganze in eine separate Klasse auslagern. Damit man es besser verwalten und überschauen kann.

Dann brauchst du nicht dem Inventar erst das Item per add zu geben nur, um es danach nochmal per Iteration zu überschreiben.

Dann solltest du in der Iteration nicht jedes mal das Inventar öffnen. Weil du öffnest es dann einfach 9 mal hintereinander.

Bei der Initialisierung des Inventars solltest du noch überlegen ob du wirklich 9 * 1 rechnen willst. Das nur nen unnötiger Rechenschritt der ausgeführt wird.
 

Michelus

Minecrafter
Registriert
5 März 2020
Beiträge
6
Diamanten
300
Hey Vestri,

also mein Plan war das alle Scheiben Grau sind und sie dann von links nach rechts zu grün werden. Wenn ich dich richtig verstanden habe ist das mit den grauen Scheiben schon okay aber sollte denn etwas einbauen was guckt ob die Scheibe schon grau ist und wenn sie das schon ist durch grüne ersetzen? Und die Klasse ist denn für die Items oder Lager ich den Scheduler auch mit aus?
 

Vestri

Minecrafter
Registriert
30 März 2012
Beiträge
8
Alter
36
Diamanten
252
Minecraft
Vestri
Im besten fall lagerst du alles aus. Das der CommandExecutor nur überprüft das der Befehl von einem Spieler kommt und dann ein Objekt von der Klasse erstellt oder es an einen Manager schickt, der sich um so was kümmert.

Das mit den Scheiben wäre dann z.B so (Ist nur nen grobes Beispiel wie man es machen kann. Gibt auch noch schönere und performantere Varianten, um das zu lösen) :

Beispiel:
        dein Task anfang

        ........

        for (int i = 0; i < inv.getSize(); i++)
        {
            if (inv.getItem(i).getType() != Material.GREEN_STAINED_GLASS_PANE)
            {
                inv.setItem(i,DeineGrüneSchreibeDieDuIrgendwoAndersInitialisiertAlsStatic);
                p.updateInventory();
                if (i == inv.getSize()-1)
                {
                    und wenn er hier ankommt sind alle schreiben grün und du kannst den Task beenden
                }
                else   
                {
                    break;
                }
            }
        }

       ........

      dein Task ende


Dadurch würde dann mit jedem Durchlauf eine Scheibe ersetzt werden bis alle Grün sind.
 

Vestri

Minecrafter
Registriert
30 März 2012
Beiträge
8
Alter
36
Diamanten
252
Minecraft
Vestri
Da gibts verschiedene Möglichkeiten.

Du kannst:

Eine Managerklasse erstellen in der die Items und Task verwaltet werden. Wo dann einfach immer nen neuer Task geöffnet wird, seinen Job erledigt und entfernt wird.

Oder du baust eine Klasse wo du einfach alles zusammen drin ist und du einfach immer ein Objekt von erzeugst, wenn du die GUI brauchst. Wenn die GUI durchgelaufen ist, wird das Objekt einfach wieder entfernt und fertig.

Es gibt noch ne paar mehr Möglichkeiten das zu verwalten.

Hier nen Beispiel wie man es machen könnte (Ist nur damit du dir das grob vorstellen kannst, solltest du so nicht verwenden.)

Beispiel:
public class OpenInvCommand implements CommandExecutor
{
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
    {
        if (sender instanceof Player)
        {
           new VoteGUI(((Player) sender).getPlayer());
           return true;
        }
        return false;
    }
}

public class VoteGUI
{
    private final Player p;

    private Inventory inv;

    BukkitTask task;

    private ItemStack grueScheibe;

    private ItemStack grauScheibe;

    public VoteGUI(Player player)
    {
        this.p = player;
        erstelleScheiben();
        erstelleUndOeffneGUI(); //erstelleScheiben und erstelleUndOeffneGUI könnte man auch in einem GUIManager auslagern und sich hier einfach nur die fertige GUI holen
        task = Bukkit.getScheduler().runTaskTimerAsynchronously(FCore.getInstance(), this::durchlaufGUI, 0, 20);
    }

    private void erstelleScheiben()
    {
        ItemStack item = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
        ItemMeta itemMeta = item.getItemMeta();
        itemMeta.setDisplayName("§7Bitte habe einen Moment geduld...");
        item.setItemMeta(itemMeta);
        grauScheibe = item;

        item = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
        itemMeta = item.getItemMeta();
        itemMeta.setDisplayName("");
        item.setItemMeta(itemMeta);

        grueScheibe = item;
    }

    private void erstelleUndOeffneGUI()
    {
        Inventory inventory = Bukkit.createInventory(null, 9, "§aMenü");

        for (int i = 0; i < inventory.getSize(); i++)
        {
            inventory.setItem(i, grauScheibe);
        }
        this.inv = inventory;
        p.openInventory(inv);
    }


    private void durchlaufGUI()
    {
        for (int i = 0; i < inv.getSize(); i++)
        {
            if (inv.getItem(i).getType() != Material.GREEN_STAINED_GLASS_PANE)
            {
                inv.setItem(i, grueScheibe);
                p.updateInventory(); //weis grade nicht auswendig ob das nicht in nem sync Task laufen muss zum updaten
                if (i == inv.getSize()-1)
                {
                    task.cancel();
                }
                return;
            }
        }
    }
}
 
Oben