我正在制作一个Bukkit插件,它将任何玩家下方的方块改为发光石。
调度程序无法正常工作。地面将变为发光石,但发光石块不会恢复为原来的状态。
@EventHandler
public void onStep(PlayerMoveEvent pme) {
Player player = pme.getPlayer();
Location locUnderPlayer = player.getLocation();
locUnderPlayer.setY(locUnderPlayer.getY() - 1);
Location locForScheduler = player.getLocation();
locForScheduler.setY(locForScheduler.getY() + 1);
final Material materialForScheduler = locForScheduler.getBlock().getType();
Block block = locUnderPlayer.getBlock();
Material m = player.getItemInHand().getType();
if (m == Material.GLOWSTONE) {
if (block.getType() != Material.AIR && block.getType() != Material.WATER && block.getType() != Material.STATIONARY_WATER && block.getType() != Material.LAVA && block.getType() != Material.STATIONARY_LAVA && block.getType() != Material.REDSTONE_WIRE && block.getType() != Material.REDSTONE_COMPARATOR && block.getType() != Material.REDSTONE_TORCH_ON && block.getType() != Material.REDSTONE_TORCH_OFF) {
block.setType(Material.GLOWSTONE);
Bukkit.getScheduler().scheduleSyncDelayedTask(Magic.getInstance(), new Runnable() {
public void run() {
block.setType(materialForScheduler);
}
}, 1 * 10);
}
}
}
最佳答案
要使障碍物位于玩家下方,您可以使用:
Block block = player.getLocation().subtract(0, 1, 0).getBlock();
这将获得玩家的位置,并从Y轴上减去1,然后获得区块(因此将区块获取到玩家下方)。
然后要获取类型,可以使用
block.getType()
:Material type = block.getType();
要将块设置为发光石,可以使用
block.setType(Material)
:block.setType(Material.GLOWSTONE);
因此,如果您想将播放器下方的方块设置为发光石,然后立即将其转回原始方块,则可以使用:
Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
Material type = block.getType(); //get the block's type
block.setType(Material.GLOWSTONE); //set the block's material to glowstone
block.setType(type); //set the block's material back to the original material
但是要在将块设置为发光石然后将其设置回原始块之间有一个延迟(在您的情况下,延迟为10个滴答),可以使用
Runnable
任务:final Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
final Material type = block.getType(); //get the block's type
block.setType(Material.GLOWSTONE); //set the block's material to glowstone
Bukkit.getScheduler().runTaskLater(Magic.getInstance(), new Runnable(){
public void run(){
block.setType(type); //set the block back to the original block
}
},10L);
我们要确保播放器下方的方块尚未发光,以确保方块更改不会永久发生。可以使用以下简单方法完成:
if(!type.equals(Material.GLOWSTONE))
如果我们不检查这一点,那么玩家可以用手拿着发光石移动,从而将其下方的方块设置为发光石,然后启动计时器将其设置回原始方块。但是,如果播放器在计时器处于运行状态时移动(例如,上一次移动后5个滴答声),则其下方的方块将永久变为发光石。
因此,您的代码可能看起来像这样:
@EventHandler
public void onStep(PlayerMoveEvent pme) {
Player player = pme.getPlayer(); //get the player in the event
final Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
final Material type = block.getState().getType(); //get the block's material
if(!type.equals(Material.GLOWSTONE)){//don't change the block if it's already glowstone
if(player.getItemInHand() != null){//make sure the item in the player's hand is not null, to avoid a null pointer
Material m = player.getItemInHand().getType(); //get the item in the player's hand
if(m == Material.GLOWSTONE){ //check if the item in the player's hand is glowstone
if(type != Material.AIR && type != Material.WATER && type != Material.STATIONARY_WATER && type != Material.LAVA && type != Material.STATIONARY_LAVA && type != Material.REDSTONE_WIRE && type != Material.REDSTONE_COMPARATOR && type != Material.REDSTONE_TORCH_ON && type != Material.REDSTONE_TORCH_OFF){
block.setType(Material.GLOWSTONE);//set the block type to glowstone
Bukkit.getScheduler().runTaskLater(Magic.getInstance(), new Runnable() {
public void run(){
block.setType(type); //set the block type back to the original type
}
},10L);
}
}
}
}
}
另外,您可以减少以下
if
语句:if(type != Material.AIR && type != Material.WATER && type != Material.STATIONARY_WATER && type != Material.LAVA && type != Material.STATIONARY_LAVA && type != Material.REDSTONE_WIRE && type != Material.REDSTONE_COMPARATOR && type != Material.REDSTONE_TORCH_ON && type != Material.REDSTONE_TORCH_OFF)
简化为
type.isSolid()
:if(type.isSolid())
关于java - 将任何玩家下方的方块设置为发光石,然后将其设置回原始 Material ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28271512/