MinecratにEntityを追加してみる その2【1.7.10】

#はじめに
前回の続きになります。前回の記事はこちら : 
[**MinecratにEntityを追加してみる その1【1.7.10】**]
(https://qiita.com/Onmitsu600/items/de614755be412337f554)
前回は、基本的な無機能Entityを実装しました。
今回はその内容、具体的な挙動を作っていきます。

#開発環境 ᕕ( ᐛ )ᕗ
- Windows 10
- Minecraft 1.7.10
- MinecraftForge 1.7.10 #1614
- IntelliJ IDEA 2019.1.3

#作っていきましょう！
##Entityに機能を付ける
そのまえに、親クラスから要求されるメソッドの解説です。

***protected void onImpact(MovingObjectPosition mop)***

>onUpdate内でmopがnullでない場合に必ず呼ばれる ベース以外の挙動をさせたい時に使う
- **MovingObjectPosition mop** : Entityの速度、ベクトル、位置、ヒットしたブロックの座標などを取得できる

今回のように簡単な機能であれば、このメソッドだけで完結できます。
しかし、複雑な挙動をさせたい場合は、onUpdateメソッドをsuperタイプを呼んだ後に新たな処理を
書いて上げる必要があります。また、EntityThrowableを継承せず、全てオリジナルで書くのもありです。

それでは、中身を書いていきます。解説しにくいのでコード内に直接書かせてもらいます。

```java:EntityPlow.java
    @Override
    protected void onImpact(MovingObjectPosition mop)
    {
//      mopのnullチェック ヒット判定が見当たらない場合エラーが出るのでそれの回避
        if(mop != null)
        {
//          Entityが当たったブロックを中心に3x3を耕したいので処理をで繰り返す
            for (int x = mop.blockX - 1; x <= mop.blockX + 1; x++)
            {
                for (int z = mop.blockZ - 1; z <= mop.blockZ + 1; z++)
                {
//                  置き換えたいブロックを取得する
                    Block i1 = this.worldObj.getBlock(x, mop.blockY, z);

//                  もしブロックが草ブロックまたは土だった場合
                    if (i1 == Blocks.grass || i1 == Blocks.dirt)
                    {
                        if (!this.worldObj.isRemote)
                        {
//                          ブロックを設置する
                            this.worldObj.setBlock(x, mop.blockY, z, Blocks.farmland);
                        }
                    }
                }
            }
        }
    }
```

こんな感じになります。いろいろメソッドを使っていますが、
大体は名前のとおりなので、バニラのクラスなりを参照してみてください。

##Entityのレンダラーを作る
このままでは、前回の記事の最後にのせたように、謎の白い箱が飛び出すだけのダサい感じになってしまいます。
なので、バニラのエンダーパールのようにかっこいい演出をしてくれるレンダラーを追加します。

バニラのクラスに**RenderManager**というのがあるんですが、そこではMinecraft内の全レンダリングの
登録などを管理しているようです。困ったときはそこを参照するといいかもしれません。
そこにある、エンダーパールの分はこうなっています。挙動は雪玉と同じなので流用しているみたいです。
なのでこいつにも流用します。
![73b8b980cee77047882386e1adc76c29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/e81bbba0-3a37-a809-3ada-a98a78379cef.png)

ClientProxyの中にこのように記述します。
registerRenders()はベースとなるクラスの事前初期化処理で呼ばれるようにしておきましょう。


```java

package mangalam.mineplus.client;

public class ClientProxy extends CommonProxy {

    public void registerRenders()
    {
        RenderingRegistry.registerEntityRenderingHandler(EntityPlow.class, new RenderSnowball(ItemRegistry.testPlow));
    }
}
```

***registerEntityRenderingHandler(EntityPlow.class, new RenderSnowball(ItemRegistry.testPlow));***
=>
***public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)***

>Entityのレンダラーを追加する 1つのEntity限定
- **Class<? extends Entity> entityClass** : レンダラーを適用するEntity
- **Render renderer** : レンダラー

せっかくなのでアイテムを日本語化して、テクスチャも追加しておきました。
人に当たるといたそうです。そういう処理もついてると面白いかもしれませんね。![2b7c4e0326c1148617adc78d2a942534.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/823ead8e-10e5-53a4-9c63-03ae1b7cb69f.png)

##プレイしてみる
コンセプト通りのコードが書けたのでプレイしてチェックしてみます。
![testplowthrow.gif](https://media.giphy.com/media/m9YWkc1kVcHOLbqO4P/giphy.gif)

いい感じですね！よく見るとわかるんですが、Entityが消えるまでの判定がシビアで、3x4とかで耕される時もあります。
ぶっちゃけ今回はEntityを追加するのが目的なので、細かい処理は割愛させてもらいます。
もっと正確にやるなら、自分ならEntityItemのコード内から位置情報の処理を見つけてそれを流用してonUpdateを作り直すって感じでしょうか。
まぁそこを考え出すともっと複雑になるので今回はやめておきます。

#終わりに
Entityの実装って思っていたより簡単なんですよね。
2年くらい前に挑戦して数分で諦めた記憶がありますが、
バニラのソースを眺めてForgeのサイト見てたらできるようになりました。
結構バニラのソース使い回しでいいものができるので、
皆様使えるものはじゃんじゃん使ってもっづぃんぐしてください。

**それでは皆様良きもっづぃんぐライフを！**