提供: Minecraft Modding Wiki
この編集を取り消せます。
下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 | 編集中の文章 | ||
1行目: | 1行目: | ||
{{前提チュートリアル|page=1.7のパケットについて}} | {{前提チュートリアル|page=1.7のパケットについて}} | ||
− | {{前提MOD|reqmod="Minecraft Forge Universal 10.12. | + | {{前提MOD|reqmod="Minecraft Forge Universal 10.12.0.xxx~"}} |
− | |||
37行目: | 36行目: | ||
} | } | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
SampleKeyCore.java(importは省略) | SampleKeyCore.java(importは省略) | ||
<source lang = "java"> | <source lang = "java"> | ||
65行目: | 44行目: | ||
@SidedProxy(clientSide = "yourpackage.Client.ClientProxy", serverSide = "yourpackage.CommonProxy") | @SidedProxy(clientSide = "yourpackage.Client.ClientProxy", serverSide = "yourpackage.CommonProxy") | ||
public static CommonProxy proxy; | public static CommonProxy proxy; | ||
− | + | //パケットハンドラー。解説は前提記事を参照のこと。 | |
+ | public static final PacketPipeline packetPipeline = new PacketPipeline(); | ||
@EventHandler | @EventHandler | ||
− | public void | + | public void load(FMLInitializationEvent event) { |
− | + | packetPipeline.initialise(); | |
+ | packetPipeline.registerPacket(KeyHandlingPacket.class);//パケットの登録 | ||
+ | FMLCommonHandler.instance().bus().register(this);//KeyHandlingEvent用 | ||
+ | MinecraftForge.EVENT_BUS.register(this);//LivingUpdate用 | ||
} | } | ||
− | |||
@EventHandler | @EventHandler | ||
− | public void | + | public void postInit(FMLPostInitializationEvent event) { |
− | + | packetPipeline.postInitialise(); | |
} | } | ||
+ | //キーが押されたかどうかを保存する変数 | ||
+ | public static boolean pressSampleKey = false; | ||
//キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 | //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 | ||
@SubscribeEvent | @SubscribeEvent | ||
public void KeyHandlingEvent(KeyInputEvent event) { | public void KeyHandlingEvent(KeyInputEvent event) { | ||
− | + | while (ClientProxy.sampleKey.isPressed()) { | |
− | + | pressSampleKey = true;//クライアント側のみの変更。 | |
+ | } | ||
+ | } | ||
+ | @SubscribeEvent | ||
+ | public void LivingUpdate(LivingUpdateEvent event) { | ||
+ | if (event.entityLiving != null && event.entityLiving instanceof EntityPlayer) { | ||
+ | if (event.entityLiving.worldObj.isRemote) { | ||
+ | //ここで、クライアントでの変数の変更をサーバーに伝える。 | ||
+ | packetPipeline.sendToServer(new KeyHandlingPacket(pressSampleKey )); | ||
+ | } | ||
+ | if (pressSampleKey) { | ||
+ | //クライアントとサーバーの両方で呼ばれる。ここに必要な処理を記述 | ||
+ | pressSampleKey = false;//呼ばれ続けるため、ここでクリア | ||
+ | } | ||
} | } | ||
} | } | ||
} | } | ||
</source> | </source> | ||
− | + | KeyHandlingPacket.java | |
<source lang = "java"> | <source lang = "java"> | ||
package yourpackage; | package yourpackage; | ||
− | + | ||
import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||
+ | import io.netty.channel.ChannelHandlerContext; | ||
+ | import net.minecraft.entity.player.EntityPlayer; | ||
+ | |||
+ | //クライアント側でキー入力によって変化したboolean変数をサーバー側に伝達するパケット。AbstractPacketを継承 | ||
+ | public class KeyHandlingPacket extends AbstractPacket | ||
+ | { | ||
+ | //保持しておくboolean型変数 | ||
+ | boolean pressSampleKey; | ||
− | public | + | //引数を持つコンストラクタを追加する場合は、空のコンストラクタを用意してくれとのこと。 |
+ | public KeyHandlingPacket() { | ||
+ | } | ||
− | + | //パケット生成を簡略化するために、boolean型変数を引数に取るコンストラクタを追加。 | |
+ | public KeyHandlingPacket(boolean ver1) { | ||
+ | pressSampleKey = ver1; | ||
+ | } | ||
− | + | @Override | |
+ | public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { | ||
+ | //ByteBufに変数を代入。基本的にsetメソッドではなく、writeメソッドを使う。 | ||
+ | buffer.writeBoolean(pressSampleKey); | ||
+ | } | ||
− | + | @Override | |
− | + | public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { | |
− | + | //ByteBufから変数を取得。こちらもgetメソッドではなく、readメソッドを使う。 | |
+ | pressSampleKey = buffer.readBoolean(); | ||
+ | } | ||
− | + | @Override | |
− | + | public void handleClientSide(EntityPlayer player) { | |
− | + | //今回はクライアントの情報をサーバーに送るので、こちらはなにもしない。 | |
− | + | } | |
− | + | @Override | |
− | + | public void handleServerSide(EntityPlayer player) { | |
− | + | SampleKeyCore.pressSampleKey = pressSampleKey; | |
− | + | } | |
} | } | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==解説== | ==解説== | ||
===ClientProxy=== | ===ClientProxy=== | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package yourpackage.client; | + | package yourpackage.client; |
import yourpackage.CommonProxy; | import yourpackage.CommonProxy; | ||
import net.minecraft.client.settings.KeyBinding; | import net.minecraft.client.settings.KeyBinding; | ||
153行目: | 148行目: | ||
===KeyInputEvent=== | ===KeyInputEvent=== | ||
<source lang = "java"> | <source lang = "java"> | ||
− | // | + | //キーが押されたかどうかを保存する変数 |
public static boolean pressSampleKey = false; | public static boolean pressSampleKey = false; | ||
//キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 | //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。 | ||
− | + | @SubscribeEvent | |
public void KeyHandlingEvent(KeyInputEvent event) { | public void KeyHandlingEvent(KeyInputEvent event) { | ||
− | + | while (ClientProxy.sampleKey.isPressed()) { | |
− | + | pressSampleKey = true;//クライアント側のみの変更。 | |
} | } | ||
} | } | ||
165行目: | 160行目: | ||
1.7より追加されたイベント。いづれかのキーが押された時に、呼ばれる。<br> | 1.7より追加されたイベント。いづれかのキーが押された時に、呼ばれる。<br> | ||
どのキーが押されたかはeventに保存されていないので、用意しているKeyBinding変数のメソッドを利用する必要が有る。<br> | どのキーが押されたかはeventに保存されていないので、用意しているKeyBinding変数のメソッドを利用する必要が有る。<br> | ||
+ | isPressedメソッドはキーが“押された回数”が0以上の時にtrueになるが、呼ばれた際に、押された回数を1減らす。 | ||
+ | チャタリング等の防止のため、while文で押された回数が0になるまで呼んでいる。 | ||
+ | このため、同じキーの登録被りが起こった場合確実にどちらかは動作しなくなる。 | ||
+ | 中途半端に動作するよりは良いので、この方法をとっている。<br> | ||
このイベントはクライアント側のみであるので、サーバーにキー判定を伝えるにはパケットを送る必要が有る。 | このイベントはクライアント側のみであるので、サーバーにキー判定を伝えるにはパケットを送る必要が有る。 | ||
− | === | + | ===KeyHandlingPacket=== |
<source lang = "java"> | <source lang = "java"> | ||
package yourpackage; | package yourpackage; | ||
− | + | ||
import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||
+ | import io.netty.channel.ChannelHandlerContext; | ||
+ | import net.minecraft.entity.player.EntityPlayer; | ||
+ | |||
+ | //クライアント側でキー入力によって変化したboolean変数をサーバー側に伝達するパケット。AbstractPacketを継承 | ||
+ | public class KeyHandlingPacket extends AbstractPacket | ||
+ | { | ||
+ | //保持しておくboolean型変数 | ||
+ | boolean pressSampleKey; | ||
− | public | + | //引数を持つコンストラクタを追加する場合は、空のコンストラクタを用意してくれとのこと。 |
+ | public KeyHandlingPacket() { | ||
+ | } | ||
− | + | //パケット生成を簡略化するために、boolean型変数を引数に取るコンストラクタを追加。 | |
+ | public KeyHandlingPacket(boolean ver1) { | ||
+ | pressSampleKey = ver1; | ||
+ | } | ||
− | + | @Override | |
+ | public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { | ||
+ | //ByteBufに変数を代入。基本的にsetメソッドではなく、writeメソッドを使う。 | ||
+ | buffer.writeBoolean(pressSampleKey); | ||
+ | } | ||
− | + | @Override | |
− | + | public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { | |
− | + | //ByteBufから変数を取得。こちらもgetメソッドではなく、readメソッドを使う。 | |
+ | pressSampleKey = buffer.readBoolean(); | ||
+ | } | ||
− | + | @Override | |
− | + | public void handleClientSide(EntityPlayer player) { | |
− | + | //今回はクライアントの情報をサーバーに送るので、こちらはなにもしない。 | |
− | + | } | |
− | + | @Override | |
− | + | public void handleServerSide(EntityPlayer player) { | |
− | + | SampleKeyCore.pressSampleKey = pressSampleKey; | |
− | + | } | |
} | } | ||
</source> | </source> | ||
− | + | キー判定を送るパケットクラス。 | |
− | + | 1つのクラスで両方向のパケットの記述が可能なため、慣れると重宝する。 | |
− | + | ここでは、pressSampleKeyの内容をサーバーに送っている。 | |
− | === | + | ===キー判定後の処理部分=== |
<source lang = "java"> | <source lang = "java"> | ||
− | + | @SubscribeEvent | |
− | + | public void LivingUpdate(LivingUpdateEvent event) { | |
− | + | if (event.entityLiving != null && event.entityLiving instanceof EntityPlayer) { | |
− | + | if (event.entityLiving.worldObj.isRemote) { | |
− | + | //ここで、クライアントでの変数の変更をサーバーに伝える。 | |
− | + | packetPipeline.sendToServer(new KeyHandlingPacket(pressSampleKey )); | |
− | public | + | } |
− | + | if (pressSampleKey) { | |
− | + | //クライアントとサーバーの両方で呼ばれる。ここに必要な処理を記述 | |
− | + | pressSampleKey = false;//呼ばれ続けるため、ここでクリア | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
</source> | </source> | ||
− | + | キー判定で処理を行う方法はいくつかあるが、今回はLivingUpdateEventを利用する。<br> | |
− | + | まず、EntityPlayerから呼ばれているかを判定している。 | |
− | + | 次にisRemote変数がtrue、つまりクライアント側でパケットをサーバーに送信。 | |
+ | 同期されるので、pressSampleKey判定はクライアントとサーバー両方で、同じ結果を得る。<br> | ||
+ | このif文内でpressSampleKeyをfalseに戻さないと、一度キーを押したら実行されっぱなしになる。<br> | ||
押しっぱなしかどうかを見たいのであれば、tick処理ループ内で、KeyBinding変数のgetIsKeyPressed()メソッドを監視し続ければよい。 | 押しっぱなしかどうかを見たいのであれば、tick処理ループ内で、KeyBinding変数のgetIsKeyPressed()メソッドを監視し続ければよい。 |