この記事は1.7のパケットについてを読んだ事を前提としています。 |
この記事は"Minecraft Forge Universal 10.12.1.1090~"を前提MODとしています。 |
この記事の古いバージョン(Minecraft Forge Universal 10.12.1.1089以前)はここより見ることができます。 |
目次
1.6におけるキーの処理
1.6までは、KeyHandlerクラスを継承して、KeyUpとKeyDownをtick単位で見ることが出来ました。 1.7では、tick処理自体がイベントになったので、キーの処理もイベントになりました。
1.7でのキーイベント追加
キーイベントの追加方法
ソースコード
CommonProxy.java
package yourpackage; //ClientProxyのみ必要だが、拡張性も考えCommonProxyも用意。GUI等追加するなら、IGuiHandlerを実装のこと。 public class CommonProxy { public void registerClientInfo(){} }
ClientProxy.java
package yourpackage.client; import yourpackage.CommonProxy; import net.minecraft.client.settings.KeyBinding; import cpw.mods.fml.client.registry.ClientRegistry; public class ClientProxy extends CommonProxy { //キーのUnlocalizedName、バインドするキーの対応整数値(Keyboardクラス参照のこと)、カテゴリー名 public static final KeyBinding sampleKey = new KeyBinding("Key.sample", Keyboard.KEY_R, "CategoryName"); @Override public void registerClientInfo() { ClientRegistry.registerKeyBinding(sampleKey); } }
PacketHandler.class
package yourpackage; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; public class PacketHandler { //このMOD用のSimpleNetworkWrapperを生成。チャンネルの文字列は固有であれば何でも良い。MODIDの利用を推奨。 public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("KeySampleMod"); public static void init() { INSTANCE.registerMessage(MessageSample.class, MessageSample.class, 0, Side.SERVER); } }
SampleKeyCore.java(importは省略)
package yourpackage; @Mod(modid="KeySampleMod", name="KeySampleMod", version="1.0") public class SampleKeyCore { @SidedProxy(clientSide = "yourpackage.Client.ClientProxy", serverSide = "yourpackage.CommonProxy") public static CommonProxy proxy; @EventHandler public void preInit(FMLPreInitializationEvent event) { PacketHandler.init(); } @EventHandler public void load(FMLInitializationEvent event) { FMLCommonHandler.instance().bus().register(this);//KeyHandlingEvent用 } //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 @SubscribeEvent public void KeyHandlingEvent(KeyInputEvent event) { if (ClientProxy.sampleKey.isPressed()) { PacketHandler.INSTANCE.sendToServer(new MessageKeyPressed(1));//1をサーバーに送る。 } } }
MessageKeyPressed.java
package yourpackage; import cpw.mods.fml.common.network.simpleimpl.IMessage; import io.netty.buffer.ByteBuf; public class MessageKeyPressed implements IMessage { public byte key; public MessageKeyPressed(){} public MessageKeyPressed(byte keyPressed) { this.key = keyPressed; } @Override public void fromBytes(ByteBuf buf) { this.key = buf.readByte(); } @Override public void toBytes(ByteBuf buf) { buf.writeByte(this.key); } }
MessageKeyPressedHandler.java
package yourpackage; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import net.minecraft.entity.player.EntityPlayer; public class MessageKeyPressedHandler implements IMessageHandler<MessageKeyPressed, IMessage> { @Override public IMessage onMessage(MessageKeyPressed message, MessageContext ctx) { EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity; //受け取ったMessageクラスのkey変数の数字をチャットに出力 entityPlayer.addChatComponentMessage(new ChatComponentText(String.format("Received byte %d", message.key))); return null; }
解説
ClientProxy
package yourpackage.client;tProxy=== import yourpackage.CommonProxy; import net.minecraft.client.settings.KeyBinding; import cpw.mods.fml.client.registry.ClientRegistry; public class ClientProxy extends CommonProxy { //キーのUnlocalizedName、バインドするキーの対応整数値(Keyboardクラス参照のこと)、カテゴリー名 public static final KeyBinding sampleKey = new KeyBinding("Key.sample", Keyboard.KEY_R, "CategoryName"); @Override public void registerClientInfo() { ClientRegistry.registerKeyBinding(sampleKey); } }
KeyBindingは1.6からインスタンス生成時の引数に“カテゴリー名”が追加されている。
キーのローカライズはlangファイル利用。
KeyBindingクラスとClientRegistryクラスはクライアント側のみなので、Proxyで分ける必要がある。
KeyInputEvent
//キーが押されたかどうかを保存する変数tEvent=== public static boolean pressSampleKey = false; //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 @SubscribeEvent public void KeyHandlingEvent(KeyInputEvent event) { if (ClientProxy.sampleKey.isPressed()) { PacketHandler.INSTANCE.sendToServer(new MessageKeyPressed(1));//1をサーバーに送る。 } }
1.7より追加されたイベント。いづれかのキーが押された時に、呼ばれる。
どのキーが押されたかはeventに保存されていないので、用意しているKeyBinding変数のメソッドを利用する必要が有る。
このイベントはクライアント側のみであるので、サーバーにキー判定を伝えるにはパケットを送る必要が有る。
MessageKeyPressed
package yourpackage; import cpw.mods.fml.common.network.simpleimpl.IMessage; import io.netty.buffer.ByteBuf; public class MessageKeyPressed implements IMessage { private byte key; public MessageKeyPressed(){} public MessageKeyPressed(byte keyPressed) { this.key = keyPressed; } @Override public void fromBytes(ByteBuf buf) { this.key = buf.readByte(); } @Override public void toBytes(ByteBuf buf) { buf.writeByte(this.key); } }
キー判定を送るMessageクラス。 ここでは、byte変数keyの内容をサーバーに送っている。
MessageKeyPressedHandler
package yourpackage; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import net.minecraft.entity.player.EntityPlayer; public class MessageKeyPressed implements IMessageHandler<MessageKeyPressed, IMessage> { @Override public IMessage onMessage(MessageKeyPressed message, MessageContext ctx) { EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity; //受け取ったMessageクラスのkey変数の数字をチャットに出力 entityPlayer.addChatComponentMessage(new ChatComponentText(String.format("Received byte %d", message.key))); return null; } }
Messageクラスを受け取って、処理をするクラス。 ここでは、サーバーのチャットに変数に格納されたbyteを出力している。
押しっぱなしかどうかを見たいのであれば、tick処理ループ内で、KeyBinding変数のgetIsKeyPressed()メソッドを監視し続ければよい。