• 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!

Listener geht nicht.

PixelEmpires

Kuhfänger
Mitglied seit
21 März 2018
Beiträge
65
Alter
18
Minecraft
_Supreme_Hero_
Hey, ich habe ein kleines Plugin programmiert, welches wenn man einen Befehl eingibt ein Skelet an einem zufälligen Ort spawnt. Wenn man es tötet soll noch ein weiteres spawnen, aber dies passiert nicht.


Ich habe diese 3 Klassen. Der Fehler muss in der Main oder in der Listener Klasse sein...

Java:
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;


public class Main extends JavaPlugin{
    public int level = 0;
    public int leben = 5;

    public void onEnable() {

    }
  
  
    public void onDisable() {
      
    }
  
  
    //warten bis Befehl ausgeführt wird
    public boolean onCommand(CommandSender sender, Command befehl, String befehlsname, String [] args) {
        if (sender instanceof Player){ //Sender muss ein Speiler sein
            Player spieler = (Player) sender;
          
          
            spieler.teleport(new Location(getServer().getWorld("Empires"),422,88,212)); //Speiler wird zur Arena teleportiert
          
            spieler.sendMessage("§6[§eEmpires§6] §eMach die bereit für den Kampf! Es geht los in: ");
            spieler.sendMessage("3");
            spieler.sendMessage("2");
            spieler.sendMessage("1");
          
            //1. Gegner wird erstellt
            Skeleton gegner1 = new Skeleton(leben , spieler, level);
            level = level + 1;
            leben = leben + 10;
            gegner1.GegnerErstellen(); //
          
            spieler.sendMessage("§6[§eEmpires§6] §eDer  Gegner wurde gespawnt! Vernichte ihn und alle weiteren!");
          
          
            //Event regestriern
            PluginManager pluginManager = this.getServer().getPluginManager();
            SkeletonDamageListener listener = new SkeletonDamageListener();
            pluginManager.registerEvents(listener, this);
          
          
          
          
          
            if (listener.skeletonHealth == true) {
                spieler.sendMessage("Du hast den Gegner Level " + level + "vernichtet!");
              
                //Neuer Gegner erstellen
                Skeleton gegner2 = new Skeleton(leben, spieler, level);
                gegner2.GegnerErstellen();
              
              
              
                if (listener.skeletonHealth == true) { //prüfen ob 2. Geggner noch lebt
                    spieler.sendMessage("Du hast beide Gegner vernichtet! Herzlichen Glückwunsch!");
                }
              
              
              
            }

                  
        }

        return true;

    }

}



Java:
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;


public class SkeletonDamageListener implements Listener{
    boolean skeletonHealth;
  
  
    public SkeletonDamageListener() {
      
    }
  
  
    @EventHandler
    public boolean EntityDamageEvent(EntityDamageEvent event) { //Wenn ein Entity Schaden zugefügt wird
      
      
        //Nun wird geprüft ob das Entity auch ein Skellet ist (vlt später überprüfen ob das Entity auch das richtige Level hat!)

        if (event.getEntityType() == EntityType.SKELETON) {
            if (event.getCause() == DamageCause.ENTITY_ATTACK) {
                if (event.getEntity().isDead() == true) {
                  
                    skeletonHealth = true;
                  
                  
                }
              
              
            }
          
          
          
        }
        return skeletonHealth;
    }
  
  
  

}




Java:
import java.util.Random;

import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;

public class Skeleton {
  
    public int leben;
    public int level;
    public Player spieler;
    public Location gegnerSpawn;
  
    public Skeleton() {
      
    }
    //Eigenschaften
    public Skeleton(int leben, Player spieler, int level) {
        this.leben = leben;
        this.spieler = spieler;
        this.level = level;
    }
  
    public void GegnerErstellen() {
        Random zufallsgenerator = new Random();
        World welt = spieler.getServer().getWorld("Empires");
      
        Location [] gegner = new Location [5];
      
        // 5 Orte wo Gegner spawnen können
        gegner [0] = new Location(welt,414,90,201);
        gegner [1] = new Location(welt,415,90,221);
        gegner [2] = new Location(welt,426,88,225);
        gegner [3] = new Location(welt,435,85,218);
        gegner [4] = new Location(welt,424,88,205);
      
        gegnerSpawn = gegner[zufallsgenerator.nextInt(gegner.length)]; // Ein Ort wird zufällig ausgewählt
      
      
        LivingEntity entity = (LivingEntity)welt.spawnEntity(gegnerSpawn, EntityType.SKELETON); //Gegner wird erstellt (Sekellet)
      
        //Eiegntchaften des Gegners:
        entity.setCustomName("§eLevel: §c" + level);
        entity.setHealth(leben);
        entity.isCustomNameVisible();
        entity.setCanPickupItems(false);
      
  
        }
}


Wäre echt nett wenn mir einer helfen könnte..... Das Problem muss wie gesagt irgendwie beim Listener liegen, da das 1. Skelet gespawnt wird, aber wenn man es tötet passiert nichts.
 

DerFrZocker

Schafhirte
Osterei Experte
Mitglied seit
10 Dezember 2017
Beiträge
126
Alter
19
Minecraft
DerFrZocker
(event.getEntity().isDead()
Das wird nie true zurück geben, da der Schaden erst nach dem Event zugefügt wird. Sprich das Skelett stirbt erst nach dem Event.

Du must das EntityDeathEvent benutzen.

if (listener.skeletonHealth == true) { spieler.sendMessage("Du hast den Gegner Level " + level + "vernichtet!"); //Neuer Gegner erstellen Skeleton gegner2 = new Skeleton(leben, spieler, level); gegner2.GegnerErstellen(); if (listener.skeletonHealth == true) { //prüfen ob 2. Geggner noch lebt spieler.sendMessage("Du hast beide Gegner vernichtet! Herzlichen Glückwunsch!"); } }
Das wird auch nie true sein. Da Java so nicht funktuniert wie du es vorhast. Ich würde dir empfehlen nochmal die Grundlagen von Java durch zu nehmen. Bzw. Wie ein Listener funktuniert.
 

PixelEmpires

Kuhfänger
Mitglied seit
21 März 2018
Beiträge
65
Alter
18
Minecraft
_Supreme_Hero_
Das 1. verstehe ich, aber beim Listener habe ich ja true in die Variable eingespeichert:
Java:
listener.skeletonHealth = true
Das Event ist ein boolean und dann habe ich die Variable returnt.... dachte das geht.
 

petomka

Minecrafter
Osterei Experte
Mitglied seit
8 Oktober 2012
Beiträge
27
Alter
19
Bis zu welcher Stelle funktioniert es denn überhaupt? Welche deiner Debug-Nachrichten werden denn gesendet? Abgesehen davon, dass es anscheinend nicht funktioniert, hast du noch einige andere Probleme bzw. Verbesserungsbedarf in deinen Klassen, die man auch als Anfänger gut umsetzen kann:
- Deine zwei Listen in Main müssen weder public noch static sein
- Genausowenig müssen die Felder in Main und Skeleton auch nicht public sein
- SkeletonDamageListener erbt von Main (und ist damit auch Unterklasse von JavaPlugin), das muss auch nicht sein und macht auch keinen Sinn
- Du fügst in deine Liste nur an Position 0 ein und liest auch nur von Position 0, damit verschwendest du Speicherplatz, da diese Liste nie wieder bereinigt wird, auch sonst wird die Struktur Liste hier falsch eingesetzt (Besser: Set)
- In der Skeleton-Klasse wird bei jedem Aufruf das Array aus Locations neu instanziert, da wäre ein einziges statisches Feld innerhalb der Klasse besser
- onCommand in Main wird ziemlich unschön bei mehr als einem Befehl
 

PixelEmpires

Kuhfänger
Mitglied seit
21 März 2018
Beiträge
65
Alter
18
Minecraft
_Supreme_Hero_
Bis zu welcher Stelle funktioniert es denn überhaupt? Welche deiner Debug-Nachrichten werden denn gesendet? Abgesehen davon, dass es anscheinend nicht funktioniert, hast du noch einige andere Probleme bzw. Verbesserungsbedarf in deinen Klassen, die man auch als Anfänger gut umsetzen kann:
- Deine zwei Listen in Main müssen weder public noch static sein
- Genausowenig müssen die Felder in Main und Skeleton auch nicht public sein
- SkeletonDamageListener erbt von Main (und ist damit auch Unterklasse von JavaPlugin), das muss auch nicht sein und macht auch keinen Sinn
- Du fügst in deine Liste nur an Position 0 ein und liest auch nur von Position 0, damit verschwendest du Speicherplatz, da diese Liste nie wieder bereinigt wird, auch sonst wird die Struktur Liste hier falsch eingesetzt (Besser: Set)
- In der Skeleton-Klasse wird bei jedem Aufruf das Array aus Locations neu instanziert, da wäre ein einziges statisches Feld innerhalb der Klasse besser
- onCommand in Main wird ziemlich unschön bei mehr als einem Befehl


Vielen Dank für deine Hilfe. Habe gestern auch vieles schon verbessert (z.B. das mit der Vererbung).Ich hab es auch geschafft, dass alles geht, aber nun möchte ich gerne die ArrayList von der Listener Klasse "wieder in die Main" bekommen.... ich weiß, dass ist das mit eienr getter-Methode machen sollte, aber naja die Umsetztung klappt noch nicht.


Ach und die Sache verstehe nicht ganz:
- In der Skeleton-Klasse wird bei jedem Aufruf das Array aus Locations neu instanziert, da wäre ein einziges statisches Feld innerhalb der Klasse besser



Das ist mein aktueller Code:
Java:
import java.util.ArrayList;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;


public class Main extends JavaPlugin{
    public int level = 0;
    public int leben = 5;
   
   
    ArrayList<UUID> entities = new ArrayList<>();
    ArrayList<Player> players = new ArrayList<>();
   


    public void onEnable() {
       
        getServer().getPluginManager().registerEvents(new SkeletonDamageListener(entities, players), this);

    }
   
   
    public void onDisable() {
       
    }
   
   

    public boolean onCommand(CommandSender sender, Command befehl, String befehlsname, String [] args) {
        if (sender instanceof Player){
            Player spieler = (Player) sender;
            players.add(0, spieler);
           
           
            spieler.teleport(new Location(getServer().getWorld("Empires"),422,88,212));
           
            spieler.sendMessage("§6[§eEmpires§6] §eMach die bereit für den Kampf! Es geht los in: ");
            spieler.sendMessage("3");
            spieler.sendMessage("2");
            spieler.sendMessage("1");
           
           

            Skeleton gegner = new Skeleton(leben , spieler, level);
            level = level + 1;
            leben = leben + 10;
           
           
            UUID entityUuid = gegner.summonSkeleton().getUniqueId();
            entities.add(entityUuid);
                       
            spieler.sendMessage("§6[§eEmpires§6] §eDer  Gegner wurde gespawnt! Vernichte ihn und alle weiteren!");
           


            if (entities.isEmpty()) {//this doesn´t work!
                spieler.sendMessage("DEBUG");
                Skeleton gegner2 = new Skeleton(leben , spieler, level);
                gegner2.summonSkeleton();
            }
           
           
           

                   
        }

        return true;

    }



}

Java:
import java.util.ArrayList;
import java.util.UUID;


import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;


public class SkeletonDamageListener implements Listener{
    private ArrayList<UUID> entities1;
    private ArrayList<Player> players;
   
    public SkeletonDamageListener() {
        // TODO Auto-generated constructor stub
    }


   
    public SkeletonDamageListener(ArrayList<UUID> entities, ArrayList<Player> players) {
        this.entities1 = entities;
        this.players = players;
       
    }
   
   
       
    @EventHandler
    public void onEntityDeathEvent(EntityDeathEvent event) { //Wenn ein Entity Schaden zugefügt wird
       
       
       
        //Nun wird geprüft ob das Entity auch ein Skellet ist (vlt später überprüfen ob das Entity auch das richtige Level hat!)

         if (entities1.contains(event.getEntity().getUniqueId())) {
            
             Player spieler = players.get(0);
             if (event.getEntity().getKiller() == spieler) {
                 spieler.sendTitle("§eGegner vernichtet!", "test", 20, 20, 20);
                 entities1.remove(event.getEntity().getUniqueId());
                
                
                
//                 Skeleton gegner = new Skeleton(leben , spieler, level);
//                 gegner.summonSkeleton();
               
            }
            
         }
    }
   
   
   
    public ArrayList<UUID> getEntities() {
        return entities1;
    }
   
    public void setEntities(ArrayList<UUID> entities) {
        this.entities1 = entities;
       
    }
   
   
   

}
Java:
import java.util.Random;

import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;



public class Skeleton {
   
    public int leben;
    public int level;
    public Player spieler;
    public Location gegnerSpawn;

   
    public Skeleton() {
       
    }
    //Eigenschaften
    public Skeleton(int leben, Player spieler, int level) {
        this.leben = leben;
        this.spieler = spieler;
        this.level = level;
    }
   
   

   
    public Entity summonSkeleton() {
       
        Random zufallsgenerator = new Random();
        World welt = spieler.getServer().getWorld("Empires");
       
        Location [] gegner = new Location [5];
       
        // 5 Orte wo Gegner spawnen können
        gegner [0] = new Location(welt,414,90,201);
        gegner [1] = new Location(welt,415,90,221);
        gegner [2] = new Location(welt,426,88,225);
        gegner [3] = new Location(welt,435,85,218);
        gegner [4] = new Location(welt,424,88,205);
       
        gegnerSpawn = gegner[zufallsgenerator.nextInt(gegner.length)]; // Ein Ort wird zufällig ausgewählt
       
        Entity entity = welt.spawnEntity(gegnerSpawn, EntityType.SKELETON);
        entity.setCustomName("§eLevel: §c" + level);
       
        LivingEntity livingEntity = (LivingEntity) entity;
        livingEntity.setHealth(leben);
        livingEntity.setCanPickupItems(false);
        livingEntity.setCustomNameVisible(true);
       
        return entity;
    }
   

       
       
       
}


Also mein Problem ist, dass ich nun die Werte aus der ArrayList von meinem Listener bekommen möchte (in der Main Zeile60 )....
 
Zuletzt bearbeitet:

petomka

Minecrafter
Osterei Experte
Mitglied seit
8 Oktober 2012
Beiträge
27
Alter
19
Hallo,

Also ich glaube du hast da etwas ganz grundlegens noch nicht richtig verstannden. Code wird immer "am Stück" ausgeführt, da wartet grundsätzlich erstmal nichts, bis ein anderer Teil deines Codes ausgeführt wurde. So etwas müsste man explizit programmieren, dann hat man es mit Parallelität und Nebenläufigkeit zu tun - das ist hier nicht der Fall und wäre auch nicht der richtige Ansatz für das Problem.

Dein Problem ist auch nicht, die Liste aus deinem Listener wieder in deine Hauptklasse zu bekommen, da jeweils eine Referenz auf die gleiche Liste ist. Als Beispiel: Stelle dir vor, deine Hauptklasse erzeugt eine Wasserflasche mit dem Namen "bottle". Diese übergibst du dann an eine weitere Klasse, diese Klasse nennt genau diese Wasserflasche aber "drink". Wenn jetzt die Hauptklasse eine Methode bei bottle (== drink) aufruft, z.B. bottle.austrinken(), so wird die andere Klasse feststellen können, dass in drink kein Wasser mehr drin ist (also z.B. drink.istLeer() == true).

Dein Problem ist nun aber folgendes:
Wird der Befehl (und damit der Code in onCommand) von einem Spieler ausgeführt, passiert nun folgendes:
  1. Spieler wird an Index 0 in eine immernoch unnötige Liste eingefügt
  2. Spieler wird teleportiert
  3. Spieler wird im Chat zugespammt
  4. Irgendwas mit Skeletten
  5. Erzeugte Entity-UUID abspeichern (Zeile 54 in Main)
  6. Nochmal Nachricht
  7. Prüfen ob gespeicherte Entity-UUIDs leer sind (Spoiler: sind sie nicht, siehe 5.)
Wird dann das erzeugte Skelett gekillt, wird der Code in deinem Listener ausgeführt. Dort entfernst du den Eintrag wieder aus den gespeicherten Entity-UUIDs.

Wenn du erwartest, dass der Code dann ab Zeile 60 in Main auf einmal weitergeht, solltest du, bevor du dich nochmal ganz dringend mit mehr Grundlagen beschäftigen.
 

PixelEmpires

Kuhfänger
Mitglied seit
21 März 2018
Beiträge
65
Alter
18
Minecraft
_Supreme_Hero_
Hallo,

Also ich glaube du hast da etwas ganz grundlegens noch nicht richtig verstannden. Code wird immer "am Stück" ausgeführt, da wartet grundsätzlich erstmal nichts, bis ein anderer Teil deines Codes ausgeführt wurde. So etwas müsste man explizit programmieren, dann hat man es mit Parallelität und Nebenläufigkeit zu tun - das ist hier nicht der Fall und wäre auch nicht der richtige Ansatz für das Problem.

Dein Problem ist auch nicht, die Liste aus deinem Listener wieder in deine Hauptklasse zu bekommen, da jeweils eine Referenz auf die gleiche Liste ist. Als Beispiel: Stelle dir vor, deine Hauptklasse erzeugt eine Wasserflasche mit dem Namen "bottle". Diese übergibst du dann an eine weitere Klasse, diese Klasse nennt genau diese Wasserflasche aber "drink". Wenn jetzt die Hauptklasse eine Methode bei bottle (== drink) aufruft, z.B. bottle.austrinken(), so wird die andere Klasse feststellen können, dass in drink kein Wasser mehr drin ist (also z.B. drink.istLeer() == true).

Dein Problem ist nun aber folgendes:
Wird der Befehl (und damit der Code in onCommand) von einem Spieler ausgeführt, passiert nun folgendes:
  1. Spieler wird an Index 0 in eine immernoch unnötige Liste eingefügt
  2. Spieler wird teleportiert
  3. Spieler wird im Chat zugespammt
  4. Irgendwas mit Skeletten
  5. Erzeugte Entity-UUID abspeichern (Zeile 54 in Main)
  6. Nochmal Nachricht
  7. Prüfen ob gespeicherte Entity-UUIDs leer sind (Spoiler: sind sie nicht, siehe 5.)
Wird dann das erzeugte Skelett gekillt, wird der Code in deinem Listener ausgeführt. Dort entfernst du den Eintrag wieder aus den gespeicherten Entity-UUIDs.

Wenn du erwartest, dass der Code dann ab Zeile 60 in Main auf einmal weitergeht, solltest du, bevor du dich nochmal ganz dringend mit mehr Grundlagen beschäftigen.

Hab alle deine Verbesserungsvorschläge nun umgesetzt, aber ich weiß nicht ganz was ich ab Zeile 60 tun sollte.....

Nach den Sommerferien lerne ich auch richtig Java in der Schule, aber ich würde dieses Plugin halt wenigstens gerne zum klappen bringen.
 
Allgemein
Hilfe Benutzer
    LottaXL LottaXL: Moin, moin =)
    Oben