弾Entityの作成
IGNISから発射する弾をEntityとして作成します。
EntityはBlockのように座標で固定されない、動きを持たせることが出来るオブジェクトです。ただし生成するだけではその場から動かないし何もしません。動きや向きの制御、接触判定、接触後の処理など、必要なことは自分で追加しないといけません。
(そのため、チュートリアル等ではアイテムやブロックに比べてやや上級向けとして扱われます。初心者が作りたくなるアイデアを最も理想に近い形で実装できる道でもあり、理解不足の初心者Modderを叩き落とす罠でもあります。)
私の場合、自作チュートリアルからソースを引っ張ってきて、改良しつつ作っていきます。チュートリアル(村人波動砲)のほうは、バニラの矢Entityを参考にしつつ作っています。
弾Entityの作成にあたり、どんなふうに作るのか考えてみます。
- Entityを貫通する
- Blockを貫通するが、貫通可能距離には限界がある
- ダメージを与える対象を選択する(火炎放射なので、火炎耐性を持っているとダメージを与えられない、など)
- 武器のエンチャントに応じた効果の強化
銃アイテムはEntityに座標や方角などの初期パラメータを与えて生成する程度のことしかしません。 実際の攻撃処理は、Entity側で行います。
実際に実装されているクラス
なお、内容はVer1.1aのものです。 記事が冗長になるため、クラス全文は別ページに移します。
Entityクラスを作る
Entityクラスを継承する
Entityを作るには、Entity.classを継承します。また、今回は弾を作るため、バニラの発射体用インターフェイスであるIProjectileを実装します。
Entity.class、IProjectileインターフェイスそれぞれ、いくつかの"必ず作らなければならないメソッド"があります。以下の状態が、弾Entityの最低限の状態です。
以下のように生成した場合、継承しているEntity.classに備わっているデフォルトの機能のみ持った状態になります。座標移動や当たり判定周りの機能は備わっていますが自力移動は出来ず、デフォルトの見た目(灰色の無地のボックス)の高さ1.8F、幅0.6F、当たり判定無しの四角い物体が、(おそらく)初期地点を選べない状態で生成されます。
package defeatedcrow.flamethrower.entity; import net.minecraft.entity.Entity; import net.minecraft.entity.IProjectile; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; public class EntityFlame extends Entity implements IProjectile { // コンストラクタ public EntityFlame(World world) { super(world); } /* Entityから実装を求められるメソッド */ @Override protected void entityInit() { } @Override protected void readEntityFromNBT(NBTTagCompound tag) { } @Override protected void writeEntityToNBT(NBTTagCompound tag) { } /* IProjectileから実装を求められるメソッド */ @Override public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { } }
- コンストラクタ
public EntityFlame(World world) { super(world); }
BlockやItemは起動時の一度だけしかインスタンスが生成されないため、通常は一種のBlock、Itemにつきコンストラクタが呼ばれるのは一度だけです。しかし、Entityはいくつでもnew Entity(world~)のように、インスタンスを生成出来ます。なので、コンストラクタもEntityの生成の度に呼ばれます。
ですから、Entityのコンストラクタの場合はBlock等と違って、個体ごとに異なる値を入れることを考えて作成します。このMODの場合、現在地や射撃の方向、ダメージ量などを生成時にEntityに渡します。
- Entityクラスから求められるメソッド
/* Entityから実装を求められるメソッド */ @Override protected void entityInit() { } @Override protected void readEntityFromNBT(NBTTagCompound tag) { } @Override protected void writeEntityToNBT(NBTTagCompound tag) { }
メソッドの中身は空でもクラッシュはしません。必要な場合のみ中身を作成します。このMODの場合は、NBTタグを読み書きしたいのでNBTのメソッド2つは中身を作っています。
- IProjectile[から求められるメソッド
@Override public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { }
発射体が飛んでいる間の速度や向きの制御。このMODの場合はXYZ方向速度から進行方向を計算して、Entityの向きを設定しています。