いままで村人ベースに作成していましたが、今回からはプレイヤーをベースに作っていきたいと考えています。Minecraftにて人間もどきを作り、サバイバルできるかを試します。システムと Entity に関する動作を知る必要があるので、時間がかかりそうです。
目標は「プレイヤーと同等の機能を備えた Entity を作成する」とします。
1. Entity の継承するクラスを辿っていく
継承するクラスの詳細はVSCodeでも確認できるのですが、継承元をたどっていくにつれてウィンドウが変わってしまうので、Eclipseを使うことにしました。
1.1 村人
村人を継承したい場合は EntityVillager
を使用しますが、このクラスはさらに継承しており、EntityAgeable
→ EntityCreature
→ EntityLiving
→ EntityLivingBase
→ Entity
となっているようです。
1.2 プレイヤー
プレイヤーを継承したい場合は EntityPlayer
を使用しますが、このクラスの継承元は EntityLivingBase
→ Entity
となっているようです。
1.3 動物(牛)
Entity は人間だけではないですね。動物も確認してみます。牛の場合は
EntityCow
→ EntityAnimal
→ EntityAgeable
→ EntityCreature
→ EntityLiving
→ EntityLivingBase
→ Entity
となっています。
1.4 モンスター (スケルトン)
モンスター(スケルトン)の場合は EntitySkeleton
→ AbstractSkeleton
→ EntityMob
→ EntityCreature
→ EntityLiving
→ EntityLivingBase
→ Entity
となっています。
1.5 モンスター(魔女)
一応敵キャラですが、人間風なので確認してみました。EntityWitch
→ EntityMob
→ EntityCreature
→ EntityLiving
→ EntityLivingBase
→ Entity
1.6 ペット(狼)
ペットはプレイヤーによる影響があるので調べてみました。EntityWolf
→ EntityTameable
→ EntityAnimal
→ EntityAgeable
→ EntityCreature
→ EntityLiving
→ EntityLivingBase
→ Entity
1.7 ボート(船)
これが意外だったのですが、ボートも Enitity の1つでした。どうやら生物に限らず、動くもの全てが Entity だそうです。EntityBoat
→ Entity
の2つだけでした。
2. EntityLivingBase クラス
ボート以外(おそらく生物)の Entity すべてが共通して継承しているのがこの EntityLivingBase
クラスです。ただ、このクラス 3000行以上あって全て読む気が全く起きないので、とりあえずメソッドを見ていきながら内容を把握していきたいと思います。
ざっと全体的に読んでみたところ「生物に関する基本クラス」のようです。 調べてもこのクラスに関する情報があまり得られなかったので、勝手に解釈していきます。
2.1 メンバ変数
クラス内のメンバ変数(定数)についてですね。パラメータが大量にあるのですが、調べても出てこなかったので推測です。
型 / クラス | メンバ変数名 | 内容(推測) |
---|---|---|
UUID | SPRINTING_SPEED_BOOST_ID | 重複しないユニークなIDの取得しているようだがよく分からない。おそらく Entity を固有IDで管理している? |
AttributeModifier | SPRINTING_SPEED_BOOST | クラス名からして描画速度もとい歩行速度とかですかね? |
IAttribute | SWIM_SPEED | 泳ぎの速さ |
DataParameter (Byte) | HAND_STATES | 手の動きに関する定数らしい。例えば食べ物食べたり、防御したり、飲むなどの動作。で、手をぷらんぷらんしているアニメーションとはまた別らしい。 |
DataParameter (Float) | HEALTH | 恐らく毒とか空腹とかの健康状態?なぜ小数点数で管理しているかは謎。もしかしたら強度かもしれない。 |
DataParameter (Integer) | POTION_EFFECTS | ポーションによる効果の強度か時間か... 整数型なので種類ではない可能性ある。 |
DataParameter (Boolean) | HIDE_PARTICLES | Entity のパーティクル(演出)の有無だと思う。 |
DataParameter (Integer) | ARROW_COUNT_IN_ENTITY | Entity の保持する矢の数?たぶんスケルトンとかディスペンサーとかに使われるのかもしれない。 |
NonNullList (ItemStack) | handInventory | withSize(2, ItemStack.EMPTY) で初期化されているので手に持つことができるアイテムストック数だと思う。バージョン 1.9 から両手持ちできるようになっているので引数が 2 なのかも? |
NonNullList (ItemStack) | armorArray | withSize(4, ItemStack.EMPTY)で初期化されているので装備できる防具数だと思う。頭、胴体、足、靴 の4装備(剣は手に持つので含まれない?) |
boolean | isSwingInProgress | 腕の歩行中スイングの有無(水に入ったらスイングしないような仕様になる?) |
EnumHand | swingingHand | 入水中の手の状態 |
とかとか色々ありましたが、多すぎて全部書くのやめましたw辛い。
メンバ変数からして動きのベースになるようなものですね。食べる、泳ぐ、歩く、飲む、矢を打つ、状態、移動方向と回転、腕の動き、カメラ視点などのパラメータをいじれるようです。
2.2 メソッド
メソッドも大量にありました。引数は省略しています。
返り値 | メソッド | 内容(推測) |
---|---|---|
constructor | EntityLivingBase | 引数に World があるのでワールド内に存在する Entity 全ての動きに関する定義を行っている? |
void | onKillCommand | /kill コマンドが実行されたときに消滅させる。これもしかして船とかも kill できるのかな? |
void | entityInit | Entity に関する登録事項。dataManager に対して登録を行っているので初期値の設定をしているのかもしれない。 |
void | updateFallState | 落下するときの速度を更新していくので加速度の意味がある? |
void | onEntityUpdate | Entity の更新に関するメソッド。腕の動きやその他パラメータなどの更新を行っている? |
void | onDeathUpdate | Entity が消滅した際に経験値をばらまいたりパーティクル(煙など)を表示させる。このロジックには isPlayer メソッドと isChild メソッドがあり、条件によって経験値のばらまく量などが変わるらしい。 |
void | knockBack | 攻撃や衝撃によるノックバックを設定するらしい。ベクトル計算をするロジックが組み込まれている。 |
void | fall | 落下の際の初期値を設定している?ジャンプ増加とかによって変わるらしい。 |
void | damageEntity | Entity のダメージ状態を決めるためのメソッド。損傷度は防具によって変化するので、それを設定している? |
void | jump | Entity のジャンプ力に関するメソッド。これもポーションなどによるジャンプ力増加などで変動するらしい。 |
このほかにもたくさんありましたが、いくつか抜粋してみました。オブジェクト指向におけるメソッドは「動作」と呼ばれているだけあって、Entity の状態やアニメーションなどに関する動きの処理をするものが大半でした。あとは判定用のロジックに組み込まれたりしていましたね。
3. Entity の継承関係
ちょっと複雑だったのでまとめてみました。
とにかく、生物に関する Entity を作成するなら EntityLivingBase
を継承するようです。自分が作りたいのは「プレイヤーと同じ構造かつタスクを割り振れる」ようなユニットなので、EntityPlayer
を継承しつつ EntityAITasks
を継承すればできそうです。ただ、子供もできるような構造にするとすれば EntityAgeable
も継承する必要があると思います。これは時間がかかりそうなので、後回しにします。
4. 作りたい人間ユニットの構成
とりあえず自分の作りたいものを整理します。
- 保持できるアイテム数や体力などはプレイヤーと同じ
- 農作業をできるような機能を搭載する
プレイヤーと同じ構成にするには EntityPlayer
を継承します。また、AI(決まった動作を行う)を搭載するために EntityAITasks
を参考にして自分でクラスを作りなおします。これをタスクとして登録することで、人間ユニットを動かします。
タスクとしての動かし方やタイミング、優先順位は他の Entity を参考にしながら頑張って作ってみようと思います。
EntityLivingBaseのスーパークラス
全ての Entity を司るクラス Entity
クラスについては分かりやすい記事を見つけたのでメモがてら貼り付けます。