2016-05-21 4 views
0

Ich bin sehr neu mit Java und wurde durch das Erstellen von Minecraft-Plugins eingeführt. Ich verwende derzeit Spigot und möchte eine Variable durch eine andere Klasse zugreifen. In diesem Plugin möchte ich, dass Spieler einen Helden mit bestimmten Fähigkeiten erschaffen können. Die zwei Klassen, die ich verwende, sind unten.JAVA/SPIGOT: Wie kann ich eine Variable aus nicht statischen Klassen aufrufen?

package me.placerwiz; 

import org.bukkit.command.Command; 

import org.bukkit.command.CommandSender; 

import org.bukkit.entity.Player; 

import org.bukkit.plugin.java.JavaPlugin; 
public class Moba extends JavaPlugin { 

    StompCooldown a; 

    @Override 
    public void onEnable() { 
     getServer().getPluginManager().registerEvents(new MenuClick(this), this); 
     new PlayerListener(this); 
     new StompAbility(this); 
     getLogger().info("This plugin has been enabled!"); 
     a = new StompCooldown(this); 
     a.runTaskTimer(this, 20, 20); 
     getCommand("pearl").setExecutor(new WarpAbility()); 
     getCommand("menu").setExecutor(this); 
    } 

    @Override 
    public void onDisable() { 

    } 

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { 

     if (cmd.getName().equalsIgnoreCase("Menu") && sender instanceof Player) { 

      Player player = (Player) sender; 
      player.openInventory(Menu.getMenu()); 

      return true; 

     } 

     return false; 
    } 

    public static void sircunningham1_1(String args[]) { 

     SirCunningham_1_1 getLoadout = new SirCunningham_1_1(); 
     getLoadout.heroChosen(); 

    } 

    public static void sircunningham2_1(String args[]) { 

     SirCunningham_2_1 getLoadout = new SirCunningham_2_1(); 
     getLoadout.heroChosen(); 

    } 

    public void gotHero(String heroChoice) { 
     if (heroChoice == "") { 

     } 
    } 

    public boolean heroTest(CommandSender sender, Command cmd, String label, String[] args) { 

     if (cmd.getName().equalsIgnoreCase("hero") && sender instanceof Player) { 

      Player player = (Player) sender; 
      player.openInventory(Menu.getMenu()); 

      return true; 

     } 

     return false; 
    }} 

Der obige Code ist meine Hauptklasse, Moba. In diesem Code wird eine Variable mit dem Namen heroChoice von der anderen Klasse empfangen. Das einzige Problem von diesem ist, dass ich möchte, dass der Code bekommt, was der Spieler als der Held ausgewählt hat. Wenn es den Helden bekommt, möchte ich, dass er den Helden erhält, den der Spieler ausgewählt hat. Gibt es trotzdem eine Variable, die ich an die Moba Klasse senden kann, nachdem der Spieler auf den letzten Inventargegenstand geklickt hat. Möglicherweise muss diese Klasse verwendet werden, wenn der Spieler die endgültige Fähigkeit für den Helden "Sir Cunningham" auswählt. (Siehe Code unten)

package me.placerwiz; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.Scanner; 

import org.bukkit.Bukkit; 
import org.bukkit.ChatColor; 
import org.bukkit.Material; 
import org.bukkit.entity.Player; 
import org.bukkit.event.EventHandler; 
import org.bukkit.event.inventory.InventoryClickEvent; 
import org.bukkit.inventory.Inventory; 
import org.bukkit.inventory.ItemStack; 
import org.bukkit.inventory.meta.ItemMeta; 

public class SirCunningham_2_1{ 
    static String hero; 
    public static Inventory getMenu(){ 

     Inventory inv = Bukkit.createInventory(null, 18, ChatColor.GREEN + ChatColor.BOLD.toString() + "Choose ultimate ability!"); 

     ItemStack item = new ItemStack(Material.IRON_BOOTS); 
     ItemMeta meta = item.getItemMeta(); 
     List<String> lore = new ArrayList<String>(); 
     lore.add(" "); 
     lore.add(ChatColor.YELLOW + "Thoughts of glory inspire your team to"); 
     lore.add(ChatColor.YELLOW + " win this battle! Everyone on your team"); 
     lore.add(ChatColor.YELLOW + " gains a buff!"); 
     meta.setLore(lore); 
     meta.setDisplayName(ChatColor.GOLD + ChatColor.BOLD.toString() + "Glory"); 
     item.setItemMeta(meta); 
     inv.addItem(item); 

     return inv; 

    } 

    @EventHandler 
    public static void onClick(InventoryClickEvent event) { 
     if (!ChatColor.stripColor(event.getInventory().getName()).equalsIgnoreCase("Choose ultimate ability!")) 
      return; 

     Player player = (Player) event.getWhoClicked(); 
     event.setCancelled(true); 

     if(event.getCurrentItem()==null || event.getCurrentItem().getType()==Material.AIR || !event.getCurrentItem().hasItemMeta()){ 
      player.closeInventory(); 
      return; 
     } 
     if(event.getCurrentItem().getType() == Material.IRON_BOOTS){ 
      player.closeInventory(); 
      String hero = "SirCunnigham_2_1"; 
      player.openInventory(Customizer.getMenu()); 
     } 
      else{ 
      player.sendMessage(ChatColor.GREEN + "[" + ChatColor.YELLOW + "MOBA" + ChatColor.GREEN + "]" + ChatColor.GOLD + "-Under Construction-"); 
      player.closeInventory(); 
     } 

    } 
    public static void heroChosen(){ 
     String heroChoice = hero; 
     Moba sendLoadout = new Moba(); 

     sendLoadout.gotHero(heroChoice); 
     } 
} 

Alles was ich brauche diese Arbeit zu erhalten, ist die String hero haben (von der if Ereignis oben), um die String heroChoice zu entsprechen. Danke für das Lesen bis jetzt und ich hoffe, dass das gelöst wird. Es bedeutet mir viel!

+0

Hey Ben, SO willkommen zu, versuchen, um ein [MCVE] für zukünftige Fragen zu posten, um schneller Hilfe zu erhalten. –

Antwort

1

Do nicht eine Variable "verstecken"! Sie haben eine statische Variable namens "hero" vom Typ String, aber Sie haben eine andere mit dem gleichen Typ und dem gleichen Namen des statischen erstellt. Du willst also den Namen des Helden bekommen.

Deklarieren Sie diese Variable static Sie machen diese Variable gleich zu allen Instanzen dieser Klasse.

Lesen Sie weiter, wenn Sie die echte Lösung kennenlernen möchten. Beachten Sie, dass die Verwendung von OOP (objektorientierte Programmierung) eine effizientere Methode ist.

Von dem, was ich von der Frage verstanden habe, möchten Sie einen Heldennamen einem Spieler zuordnen.

Sie können es einfach mit einer HashMap tun.

public static HashMap<Player,String> playerHero = new HashMap<Player,String>(); 

oder wenn Sie mit Java sind 8

public static HashMap<Player,String> playerHero = new HashMap<>(); 

Um Spieler und Held Name tun

MyClass.playerHero.put(player, heroName); 

Um die heroName vom Spieler zu erhalten:

MyClass.playerHero.get(player); 

Um die Spieler aus dem heroName: Sie können eine Methode machen:

public static List<Player> getPlayers(String heroName){ 
List<Player> players = new ArrayList<Player>(); 
for(Map.Entry<Player,String> e : MyClass.playerHero.entrySet()){ 
    if(e.getValue().equalsIgnoreCase(heroName)){ 
    players.add(e.getKey()); 
    } 
} 
return players; 
} 

Alle diese Variablen sind static, so können wir sie mit MyClass.variableName Alle diese Methoden static zugreifen, so dass wir auf sie zugreifen kann mit MyClass.method(parameters);

Hope this geholfen!

+0

Sein Problem (das er nicht genau beschreiben konnte) ist, dass das Deklarieren von allem mit einem statischen Modifikator keine gültige Lösung ist, da bestimmte Methoden, an die er seine Variablen weiterleitet, vordefinierte EventHandler aus der Bukkit API sind. Diese haben eine spezifizierte Deklaration, die keinen statischen Modifikator enthält. Wie du schon erwähnt hast, ist OOP die bessere Wahl. –

0

Sie könnten den static Modifikator für heroChoice und alle Methoden verwenden, die mit variablen arbeiten, aber das ist nicht die beste Praxis, weil in vielen Fällen werden Sie nicht in der Lage seine static zu bedienen und auch für diesen Fall können Sie nicht machen die EventHandler der Bukkit API static. Also, was machst du? Es ist einfach.

Verwenden OOP, passieren Instanz Objekts Variable durch Konstruktor aufruft

Jedes Objekt kann Konstrukteure haben, enthalten die Konstrukteurs-Code, der ausgeführt werden soll, wenn eine Instanz des Objekts erstellt wird. Sie können Paramter auch wie bei einer Methode an einen Konstruktor übergeben. Als Ergebnis können Sie einfach die gewünschte Variable aus einer Klasse in den Konstruktor des anderen übergeben und speichern. Zum Beispiel:

class Car { //my class Car 
    double topSpeedMPH; //when a Car is created, it needs to get a top speed 
    public Car(double topSpeedMPH) { //public constructor for Car, requires a double parameter 
     this.topSpeedMPH = topSpeedMPH; //set the class' topSpeedMPH variable to the local one 
    } 
} 

Dann in der rufenden Code:

double speed = 10; 
Car fordFusion = new Car(speed); 

So für Ihren Code speziell:

class Moba { 
    String heroChoice; //Moba has heroChoice stored 
    public Moba(String choice) { //Moba constructor, requires a String (which is the choice) 
     this.heroChoice = choice; //stores the parameter String to use later 
    } 
} 

class SirCunningham_2_1 { 
    public void heroChosen(){ 
     String heroChoice = hero; 
     Moba sendLoadout = new Moba(heroChoice); 
     sendLoadout.gotHero(heroChoice); 
    } 
} 

Eine andere Lösung: Verwenden Sie OOP, eine Instanz des gesamten rufenden Objekt übergeben durch Konstruktor unter Verwendung this Schlüsselwort

Die vorherige Lösung eignet sich nur für eine Variable, aber was, wenn ich auf mehrere Variablen von einem anderen Objekt zugreifen möchte? Es wäre ziemlich unpraktisch, jeden von ihnen zu individuellen Parametern zu machen. Zum Glück gibt es einen guten Weg, dies zu tun. Übergeben Sie einfach die gesamte Instanz. Das folgende Beispiel (mit Auto wieder) zeigt es:

class Motor { 
    Car myCar; 
    double topSpeed; 
    double accel; 
    public Motor(Car c) { //require instance of car 
     this.myCar = c; 
     this.topSpeed = myCar.topSpeed; //get values from instance 
     this.accel = myCar.secondsTo60; 
    } 
} 

class Car { 
    Motor m; 
    double topSpeed = 108; 
    double secondsTo60 = 8; 
    int seats = 4; 

    public Car() { 
     m = new Motor(this); //use this keyword to pass entire instance 
    } 

    void startEngine() { 
     System.out.println("Vroom Vroom!"); 
    } 
} 

Ein großer Vorteil dieser Lösung ist, dass ich auch Methoden aus der anderen Klasse verwenden:

public Motor(Car c) { //require instance of car 
     this.myCar = c; 
     this.topSpeed = myCar.topSpeed; //get values from instance 
     this.accel = myCar.secondsTo60; 
     myCar.startEngine(); 
    } 
Verwandte Themen