JAVA / SPIGOT:如何从非静态类中调用变量?

时间:2016-05-21 20:53:25

标签: java plugins minecraft

我是Java的新手,并通过创建Minecraft插件来介绍它。我目前正在使用Spigot,并希望通过另一个类访问变量。在这个插件中,我希望玩家能够创造一个具有一定能力的英雄。我使用的两个课程如下。

Activity

上面的代码是我的主要类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类。它可能需要使用这个类,玩家选择英雄的最终能力" Sir Cunningham"。 (见下面的代码)

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); } } (来自上面的if事件)等于String hero。感谢您阅读这篇文章,我希望这会得到解决。这对我来说意义重大!

2 个答案:

答案 0 :(得分:1)

“隐藏”变量!你有一个类型为String的名为“hero”的静态变量,但你创建了另一个静态变量,它具有与静态变量相同的类型和相同的名称。所以你想得到英雄的名字。

声明变量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);

从heroName获取玩家: 你可以制作一个方法:

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

访问它们

希望这有帮助!

答案 1 :(得分: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关键字

通过构造函数传递整个调用对象的实例

之前的解决方案仅适用于一个变量,但是如果我希望能够从另一个对象访问多个变量呢?将它们中的每一个作为单独的参数是相当不方便的。幸运的是,有一个很好的方法来做到这一点。只需传递整个实例即可。以下示例(再次使用Car)显示它:

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