2016-05-21 27 views
0

我對Java很陌生,通過創建Minecraft插件介紹了它。我目前使用Spigot並希望通過另一個類訪問變量。在這個插件中,我希望玩家能夠創建具有某種能力的英雄。下面是我使用的兩個類。JAVA/SPIGOT:我怎樣才能從非靜態類調用一個變量?

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; 
    }} 

上面的代碼是我的主類Moba。在這段代碼中,從另一個類接收到一個名爲heroChoice的變量。唯一的問題是我想讓代碼得到玩家選擇的英雄。當它獲得英雄時,我希望它獲得玩家選擇的英雄。無論如何,當玩家點擊最終庫存項目後,我可以獲得發送到Moba類的變量。當玩家選擇英雄「坎寧安爵士」的最終能力時,可能需要使用這個類。 (請參見下面的代碼)

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); 
     } 
} 

所有我需要得到這個工作是有String hero(從上面的,如果事件),以等於String heroChoice。感謝您閱讀這些,我希望這將得到解決。它對我意義重大!

+0

嘿本,歡迎SO,嘗試發佈[MCVE]以便將來的問題更快地獲得幫助。 –

回答

1

不是「隱藏」一個變量!您有一個名爲「hero」的類型爲String的靜態變量,但是您已經創建了另一個具有相同類型和相同名稱的靜態變量。所以你想獲得英雄的名字。

聲明該變量static您使該變量等於該類的所有實例。

如果您想知道真正的解決方案,請繼續閱讀。 注意,使用OOP(面向對象的編程)是一種更有效的方法。

從我從問題中瞭解的情況來看,你希望將英雄名稱與玩家聯繫起來。

你可以簡單地用一個HashMap來完成。

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

,或者如果您使用的是Java 8

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

要添加的球員,一個英雄的名字做

MyClass.playerHero.put(player, heroName); 

要想從玩家heroName:

MyClass.playerHero.get(player); 

爲了讓玩家從英雄名稱: 你可以做一個方法:

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; 
} 

所有這些變量都static,所以我們可以MyClass.variableName 所有這些方法都static訪問它們,所以我們可以MyClass.method(parameters);

希望這有助於訪問它們!

+0

他的問題(他可能沒有準確描述)是用靜態修飾符聲明所有東西不是一個有效的解決方案,因爲他傳遞變量的某些方法是來自Bukkit API的預定義的EventHandler。它們有一個不包含靜態修飾符的指定聲明。就像你之前提到的OOP是更好的選擇。 –

0

您可以使用static修改爲heroChoice,並與您的變量工作的所有方法,但這不是最佳做法,因爲在很多情況下,你將無法使用static,甚至這種情況下,你不能讓Bukkit API的EventHandlers static。所以你會怎麼做?這很簡單。

使用OOP,通過構造調用對象的變量

每個對象都可以有構造的情況下,構造函數包含被創建的對象的實例時將運行的代碼。您也可以將paremters傳遞給構造函數,就像您使用方法一樣。因此,您可以簡單地將您想要的變量從一個類傳遞到另一個類的構造函數中並存儲它。例如:

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 
    } 
} 

然後在調用代碼:

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

因此,對於你的代碼將專門:

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); 
    } 
} 

另一種解決方案:使用OOP,傳遞整個調用對象的實例通過構造函數使用this關鍵字

以前的解決方案僅適用於一個變量,但如果我希望能夠從另一個對象訪問多個變量,該怎麼辦?將每個參數作爲單獨的參數都是相當不方便的。幸運的是,有一個很好的方法來做到這一點。只需傳遞整個實例即可。下面的例子(再次使用汽車)顯示它:

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!"); 
    } 
} 

的一大優勢,這種解決方案是,我甚至可以使用來自其他類的方法:

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(); 
    } 
相關問題