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