Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将所有放置的砌块更换为空气,并将损坏的砌块更换为其原始材料_Java_Minecraft - Fatal编程技术网

Java 将所有放置的砌块更换为空气,并将损坏的砌块更换为其原始材料

Java 将所有放置的砌块更换为空气,并将损坏的砌块更换为其原始材料,java,minecraft,Java,Minecraft,我对spiget中的插件开发还不熟悉,最近我有了一个想法,要创建一个复杂的项目(至少对我来说是这样)。我想将所有放置的块存储到ArrayList中,与断块一样,当播放器执行resetblocks命令时,所有断块都会变成原始材质,放置的块会变成空气,但由于某种原因,它无法工作。我几乎可以肯定这是一个范围问题,我没有意识到这一点 public class ResetBlocksCommand implements CommandExecutor, Listener { List<Bl

我对spiget中的插件开发还不熟悉,最近我有了一个想法,要创建一个复杂的项目(至少对我来说是这样)。我想将所有放置的块存储到ArrayList中,与断块一样,当播放器执行resetblocks命令时,所有断块都会变成原始材质,放置的块会变成空气,但由于某种原因,它无法工作。我几乎可以肯定这是一个范围问题,我没有意识到这一点

public class ResetBlocksCommand implements CommandExecutor, Listener {

    List<Block> placedBlocks = new ArrayList<>();
    List<Block> brokenBlocks = new ArrayList<>();

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("resetblocks")) {
           for (Block block : placedBlocks) {
               Material blockMaterial = block.getType();
               blockMaterial = Material.AIR;
               sleep(500);
           }

           for (Block block : brokenBlocks) {
               Material blockMaterial = block.getType();
               blockMaterial = blockMaterial;
               sleep(500);
           }
           return true;
        }
        return true;
    }

    @EventHandler
    public void blockPlaceEvent (BlockPlaceEvent event) {
        Block block = event.getBlock();
        Bukkit.getConsoleSender().sendMessage(block.getType().name());
        placedBlocks.add(block);
    }

    @EventHandler
    public void blockBrakeEvent (BlockBreakEvent event) {
        Block block = event.getBlock();
        Bukkit.getConsoleSender().sendMessage(block.getType().name());
        brokenBlocks.add(block);
    }

    private void sleep(long milli) {
        try {
            Thread.sleep(milli);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public类resetblocks命令实现CommandExecutor、Listener{
List placedBlocks=new ArrayList();
List brokenBlocks=new ArrayList();
@凌驾
公共布尔onCommand(CommandSender、Command cmd、字符串标签、字符串[]args){
if(cmd.getName().equalsIgnoreCase(“resetblocks”)){
用于(块:placedBlocks){
Material blockMaterial=block.getType();
块状材料=材料。空气;
睡眠(500);
}
用于(块:断块){
Material blockMaterial=block.getType();
块状材料=块状材料;
睡眠(500);
}
返回true;
}
返回true;
}
@事件处理程序
公开作废blockPlaceEvent(blockPlaceEvent事件){
Block=event.getBlock();
Bukkit.getConsoleSender().sendMessage(block.getType().name());
placedBlocks.add(块);
}
@事件处理程序
公共无效blockBrakeEvent(BlockBreakEvent事件){
Block=event.getBlock();
Bukkit.getConsoleSender().sendMessage(block.getType().name());
断块。添加(块);
}
私人虚空睡眠(长毫秒){
试一试{
线程。睡眠(毫);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

PS:控制台正在打印断块和放置的块。

我已经很久没有使用spigot/bukkit了,但我相信要更改块,您需要使用
block.setType​(材料类型)而不仅仅是更改返回的物料
blockMaterial=material.AIR

这应该可以改变类型:

   for (Block block : placedBlocks) {
       block.setType(Material.AIR);
       sleep(500);
   }
要恢复断块,您将遇到另一个问题。使用
Block Block=event.getBlock()时
在你的
blockBrakeEvent
中,它获取对当前块的引用,该引用将在块被破坏之前获取当前材料,但一旦事件通过插件传递,服务器将导致破坏事件发生,块材料将变为
material.AIR
。要解决此问题,需要同时保存块和原始材质,例如:

//Create a list for the Block and the Material
List<Block> brokenBlocks = new ArrayList<>();
List<Material> brokenBlockMaterial = new ArrayList<>();

@EventHandler
public void blockBrakeEvent (BlockBreakEvent event) {
    Block block = event.getBlock();
    //Save both the block and the material to to the array
    brokenBlocks.add(block);
    brokenBlockMaterial.add(block.getType());
}
//创建块和材质的列表
List brokenBlocks=new ArrayList();
List brokenBlockMaterial=new ArrayList();
@事件处理程序
公共无效blockBrakeEvent(BlockBreakEvent事件){
Block=event.getBlock();
//将块和材质保存到阵列
断块。添加(块);
brokenBlockMaterial.add(block.getType());
}
然后,在还原循环中,您需要引用已保存的块和材质:

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    if (cmd.getName().equalsIgnoreCase("resetblocks")) {
       for (Block block : placedBlocks) {
           block.setType(Material.AIR);
           sleep(500);
       }
       //use a loop that iterates through both lists using an index
       for (int i = 0; i < brokenBlocks.size(); i++)
       {
           //Reference to the brokenBlocks list to get the block
           Block block = brokenBlocks.get(i);
           //Then use the brokenBlockMaterial list to restore/set the material type
           block.setType(brokenBlockMaterial.get(i));
           sleep(500);
       }
       return true;
    }
    return true;
}
@覆盖
公共布尔onCommand(CommandSender、Command cmd、字符串标签、字符串[]args){
if(cmd.getName().equalsIgnoreCase(“resetblocks”)){
用于(块:placedBlocks){
块。设置类型(材料。空气);
睡眠(500);
}
//使用循环,使用索引在两个列表中进行迭代
对于(int i=0;i

注意:当一名球员打破一个拦网,然后在同一地点多次放置拦网时,会发生什么情况?你需要弄清楚你将如何以正确的顺序处理一切。考虑一下前进。

注意:当你同时有多个玩家使用插件时,也要考虑一下发生了什么。考虑如何将它们分开,以便命令不会干扰其他玩家(我建议创建一个自定义对象,存储块、材质和玩家ID,这样您可以轻松确定哪个中断/放置事件与哪个玩家关联)