自定义新的事件类
我们在EventLoader
类中新建一个我们想要的事件类。
src/main/java/com/github/ustc_zzzz/fmltutor/common/EventLoader.java(部分):
@Cancelable
public static class PlayerRightClickGrassBlockEvent extends net.minecraftforge.event.entity.player.PlayerEvent
{
public final BlockPos pos;
public final World world;
public PlayerRightClickGrassBlockEvent(EntityPlayer player, BlockPos pos, World world)
{
super(player);
this.pos = pos;
this.world = world;
}
}
很明显,这个类和玩家右键草块相关。该事件类继承了PlayerEvent
,@Cancelable
注解表明了该事件可取消。
自定义事件的注册机制
在上一部分,我们注意到FMLCommonHandler.instance().bus()
和MinecraftForge.EVENT_BUS
均为EventBus
类型。该类型提供了名为register
的方法使得事件可以被注册。
显然,我们自己也可以创建这样一个EventBus
,并且使得所有自定义的事件在这里被注册。
src/main/java/com/github/ustc_zzzz/fmltutor/common/EventLoader.java(部分):
public static final EventBus EVENT_BUS = new EventBus();
使自定义事件会被触发到
EventBus
本身提供了一个名为post
的方法,负责执行事件。大家如果经常翻源代码的话,会在Minecraft的许多类中找到这个方法的调用。这里我们希望在玩家点击草块时触发,我们也如法炮制。
src/main/java/com/github/ustc_zzzz/fmltutor/block/BlockGrassBlock.java(部分):
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn,
EnumFacing side, float hitX, float hitY, float hitZ)
{
EventLoader.PlayerRightClickGrassBlockEvent event;
event = new EventLoader.PlayerRightClickGrassBlockEvent(playerIn, pos, worldIn);
EventLoader.EVENT_BUS.post(event);
if (!event.isCanceled() && !worldIn.isRemote)
{
worldIn.setBlockToAir(pos);
return true;
}
return false;
}
很明显,这段代码的意思是,如果事件被取消了,就阻止草块变成空气,否则草块就会变成空气。
自定义事件的实现
自定义事件的实现和Forge提供的完全一样,只不过我们要找准在哪里注册。
在EventLoader
类中添加一个方法。
src/main/java/com/github/ustc_zzzz/fmltutor/common/EventLoader.java(部分):
@SubscribeEvent
public void onPlayerClickGrassBlock(PlayerRightClickGrassBlockEvent event)
{
if (!event.world.isRemote)
{
BlockPos pos = event.pos;
Entity tnt = new EntityTNTPrimed(event.world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, null);
event.world.spawnEntityInWorld(tnt);
}
}
很明显,这里定义了当玩家两手空空时的行为。
然后我们注册这个事件。
src/main/java/com/github/ustc_zzzz/fmltutor/common/EventLoader.java(部分):
public EventLoader()
{
MinecraftForge.EVENT_BUS.register(this);
EventLoader.EVENT_BUS.register(this);
}
打开游戏,放置一个草块,右键点击它,三、二、一。。。BOOM