提供: Minecraft Modding Wiki
移動先: 案内検索

警告: ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。ログインまたはアカウントを作成すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。

この編集を取り消せます。 下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 編集中の文章
1行目: 1行目:
 
{{前提チュートリアル|page=1.7のパケットについて}}
 
{{前提チュートリアル|page=1.7のパケットについて}}
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}}
+
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.0.xxx~"}}
{{過去リンク|version=Minecraft Forge Universal 10.12.1.1089|url=http://minecraftjp.info/modding/index.php?title=1.7%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E8%BF%BD%E5%8A%A0&oldid=2141}}
 
  
  
37行目: 36行目:
 
}
 
}
 
</source>
 
</source>
PacketHandler.class
 
<source lang = "java">
 
 
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(MessageKeyPressedHandler.class, MessageKeyPressed.class, 0, Side.SERVER);
 
    }
 
}</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 preInit(FMLPreInitializationEvent event) {
+
     public void load(FMLInitializationEvent event) {
         PacketHandler.init();
+
         packetPipeline.initialise();
 +
        packetPipeline.registerPacket(KeyHandlingPacket.class);//パケットの登録
 +
        FMLCommonHandler.instance().bus().register(this);//KeyHandlingEvent用
 +
        MinecraftForge.EVENT_BUS.register(this);//LivingUpdate用
 
     }
 
     }
 
 
     @EventHandler
 
     @EventHandler
     public void load(FMLInitializationEvent event) {
+
     public void postInit(FMLPostInitializationEvent event) {
         FMLCommonHandler.instance().bus().register(this);//KeyHandlingEvent用
+
         packetPipeline.postInitialise();
 
     }
 
     }
 +
    //キーが押されたかどうかを保存する変数
 +
    public static boolean pressSampleKey = false;
 
     //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。
 
     //キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。
 
     @SubscribeEvent
 
     @SubscribeEvent
 
     public void KeyHandlingEvent(KeyInputEvent event) {
 
     public void KeyHandlingEvent(KeyInputEvent event) {
         if (ClientProxy.sampleKey.isPressed()) {
+
         while (ClientProxy.sampleKey.isPressed()) {
             PacketHandler.INSTANCE.sendToServer(new MessageKeyPressed(1));//1をサーバーに送る。
+
             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>
MessageKeyPressed.java
+
KeyHandlingPacket.java
 
<source lang = "java">
 
<source lang = "java">
 
package yourpackage;
 
package yourpackage;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
+
 
 
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 class MessageKeyPressed implements IMessage {
+
//引数を持つコンストラクタを追加する場合は、空のコンストラクタを用意してくれとのこと。
 +
public KeyHandlingPacket() {
 +
}
  
    public byte key;
+
//パケット生成を簡略化するために、boolean型変数を引数に取るコンストラクタを追加。
 +
public KeyHandlingPacket(boolean ver1) {
 +
pressSampleKey = ver1;
 +
}
  
    public MessageKeyPressed(){}
+
@Override
 +
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
 +
//ByteBufに変数を代入。基本的にsetメソッドではなく、writeメソッドを使う。
 +
buffer.writeBoolean(pressSampleKey);
 +
}
  
    public MessageKeyPressed(byte keyPressed) {
+
@Override
        this.key = keyPressed;
+
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
    }
+
//ByteBufから変数を取得。こちらもgetメソッドではなく、readメソッドを使う。
 +
pressSampleKey = buffer.readBoolean();
 +
}
  
    @Override
+
@Override
    public void fromBytes(ByteBuf buf) {
+
public void handleClientSide(EntityPlayer player) {
        this.key = buf.readByte();
+
//今回はクライアントの情報をサーバーに送るので、こちらはなにもしない。
    }
+
}
  
    @Override
+
@Override
    public void toBytes(ByteBuf buf) {
+
public void handleServerSide(EntityPlayer player) {
        buf.writeByte(this.key);
+
SampleKeyCore.pressSampleKey = pressSampleKey;
    }
+
}
 
}
 
}
 
</source>
 
</source>
MessageKeyPressedHandler.java
 
<source lang = "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;
 
    }
 
 
</source>
 
 
 
==解説==
 
==解説==
 
===ClientProxy===
 
===ClientProxy===
 
<source lang = "java">
 
<source lang = "java">
package yourpackage.client;tProxy===
+
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">
//キーが押されたかどうかを保存する変数tEvent===
+
//キーが押されたかどうかを保存する変数
 
public static boolean pressSampleKey = false;
 
public static boolean pressSampleKey = false;
 
//キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。
 
//キーが“押された時”に呼ばれる。“押しっぱなし”の判定は別途用意する必要あり。
    @SubscribeEvent
+
@SubscribeEvent
 
public void KeyHandlingEvent(KeyInputEvent event) {
 
public void KeyHandlingEvent(KeyInputEvent event) {
     if (ClientProxy.sampleKey.isPressed()) {
+
     while (ClientProxy.sampleKey.isPressed()) {
         PacketHandler.INSTANCE.sendToServer(new MessageKeyPressed(1));//1をサーバーに送る。
+
         pressSampleKey = true;//クライアント側のみの変更。
 
     }
 
     }
 
}
 
}
165行目: 160行目:
 
1.7より追加されたイベント。いづれかのキーが押された時に、呼ばれる。<br>
 
1.7より追加されたイベント。いづれかのキーが押された時に、呼ばれる。<br>
 
どのキーが押されたかはeventに保存されていないので、用意しているKeyBinding変数のメソッドを利用する必要が有る。<br>
 
どのキーが押されたかはeventに保存されていないので、用意しているKeyBinding変数のメソッドを利用する必要が有る。<br>
 +
isPressedメソッドはキーが“押された回数”が0以上の時にtrueになるが、呼ばれた際に、押された回数を1減らす。
 +
チャタリング等の防止のため、while文で押された回数が0になるまで呼んでいる。
 +
このため、同じキーの登録被りが起こった場合確実にどちらかは動作しなくなる。
 +
中途半端に動作するよりは良いので、この方法をとっている。<br>
 
このイベントはクライアント側のみであるので、サーバーにキー判定を伝えるにはパケットを送る必要が有る。
 
このイベントはクライアント側のみであるので、サーバーにキー判定を伝えるにはパケットを送る必要が有る。
===MessageKeyPressed===
+
===KeyHandlingPacket===
 
<source lang = "java">
 
<source lang = "java">
 
package yourpackage;
 
package yourpackage;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
+
 
 
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 class MessageKeyPressed implements IMessage {
+
//引数を持つコンストラクタを追加する場合は、空のコンストラクタを用意してくれとのこと。
 +
public KeyHandlingPacket() {
 +
}
  
    private byte key;
+
//パケット生成を簡略化するために、boolean型変数を引数に取るコンストラクタを追加。
 +
public KeyHandlingPacket(boolean ver1) {
 +
pressSampleKey = ver1;
 +
}
  
    public MessageKeyPressed(){}
+
@Override
 +
public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
 +
//ByteBufに変数を代入。基本的にsetメソッドではなく、writeメソッドを使う。
 +
buffer.writeBoolean(pressSampleKey);
 +
}
  
    public MessageKeyPressed(byte keyPressed) {
+
@Override
        this.key = keyPressed;
+
public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
    }
+
//ByteBufから変数を取得。こちらもgetメソッドではなく、readメソッドを使う。
 +
pressSampleKey = buffer.readBoolean();
 +
}
  
    @Override
+
@Override
    public void fromBytes(ByteBuf buf) {
+
public void handleClientSide(EntityPlayer player) {
        this.key = buf.readByte();
+
//今回はクライアントの情報をサーバーに送るので、こちらはなにもしない。
    }
+
}
  
    @Override
+
@Override
    public void toBytes(ByteBuf buf) {
+
public void handleServerSide(EntityPlayer player) {
        buf.writeByte(this.key);
+
SampleKeyCore.pressSampleKey = pressSampleKey;
    }
+
}
 
}
 
}
 
</source>
 
</source>
キー判定を送るMessageクラス。
+
キー判定を送るパケットクラス。
ここでは、byte変数keyの内容をサーバーに送っている。
+
1つのクラスで両方向のパケットの記述が可能なため、慣れると重宝する。
 
+
ここでは、pressSampleKeyの内容をサーバーに送っている。
===MessageKeyPressedHandler===
+
===キー判定後の処理部分===
 
<source lang = "java">
 
<source lang = "java">
package yourpackage;
+
@SubscribeEvent
import cpw.mods.fml.common.network.simpleimpl.IMessage;
+
public void LivingUpdate(LivingUpdateEvent event) {
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
+
     if (event.entityLiving != null && event.entityLiving instanceof EntityPlayer) {
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
+
         if (event.entityLiving.worldObj.isRemote) {
import net.minecraft.entity.player.EntityPlayer;
+
            //ここで、クライアントでの変数の変更をサーバーに伝える。
 
+
            packetPipeline.sendToServer(new KeyHandlingPacket(pressSampleKey ));
public class MessageKeyPressed implements IMessageHandler<MessageKeyPressed, IMessage> {
+
        }
 
+
        if (pressSampleKey) {
     @Override
+
            //クライアントとサーバーの両方で呼ばれる。ここに必要な処理を記述
    public IMessage onMessage(MessageKeyPressed message, MessageContext ctx) {
+
            pressSampleKey = false;//呼ばれ続けるため、ここでクリア
         EntityPlayer entityPlayer = ctx.getServerHandler().playerEntity;
+
         }
        //受け取ったMessageクラスのkey変数の数字をチャットに出力
 
 
 
        entityPlayer.addChatComponentMessage(new ChatComponentText(String.format("Received byte %d", message.key)));
 
         return null;
 
 
     }
 
     }
 
}
 
}
 
</source>
 
</source>
Messageクラスを受け取って、処理をするクラス。
+
キー判定で処理を行う方法はいくつかあるが、今回はLivingUpdateEventを利用する。<br>
ここでは、サーバーのチャットに変数に格納されたbyteを出力している。
+
まず、EntityPlayerから呼ばれているかを判定している。
 
+
次にisRemote変数がtrue、つまりクライアント側でパケットをサーバーに送信。
 +
同期されるので、pressSampleKey判定はクライアントとサーバー両方で、同じ結果を得る。<br>
 +
このif文内でpressSampleKeyをfalseに戻さないと、一度キーを押したら実行されっぱなしになる。<br>
 
押しっぱなしかどうかを見たいのであれば、tick処理ループ内で、KeyBinding変数のgetIsKeyPressed()メソッドを監視し続ければよい。
 
押しっぱなしかどうかを見たいのであれば、tick処理ループ内で、KeyBinding変数のgetIsKeyPressed()メソッドを監視し続ければよい。

Minecraft Modding Wikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細はMinecraft Modding Wiki:著作権を参照)。 著作権保護されている作品は、許諾なしに投稿しないでください!

このページを編集するには、下記の確認用の質問に回答してください (詳細):

取り消し 編集の仕方 (新しいウィンドウで開きます)