【Minecraft java edition 模组开发】(二):通过对岩浆怪和雪傀儡的源码分析,自己制作一个雪球怪
零、什么是實體
??實體(Entity)包括在Minecraft中所有動態的、移動中的對象。例如游戲中的怪物僵尸骷髏等,船和礦車,受重力影響的方塊如下落的沙子鐵砧等。
??我們今天要加入的東西就是一個雪球怪,它擁有和巖漿怪一樣的分裂能力,不同的是,他不能免疫灼燒傷害,和雪傀儡會受到比較熱的自然環境的傷害,并且走到哪里哪里有雪。
一、實體繼承樹
??這張圖有點糊,但是沒辦法,我從網上找不到其他圖了。
??從這張繼承樹中我們可以巖漿怪繼承自史萊姆;雪傀儡繼承自抽象類傀儡實體(傀儡實體有三個子類,雪傀儡,鐵傀儡和凋零。都是非抽象類);再進一步翻閱forge源碼,我們還會發現雪傀儡還實現了兩個接口:IRangedAttackMo用于實現怪物遠程攻擊,女巫,骷髏等也實現了這個接口,IShearable用于實現可剪裁,羊雪傀儡都實現了。
??巖漿怪:
public class EntityMagmaCube extends EntitySlime{/* codes */}??雪傀儡:
public class EntitySnowman extends EntityGolem implements IRangedAttackMob, net.minecraftforge.common.IShearable{/* codes */}二、編寫雪球怪的代碼:
??1.首先既然雪球怪要和巖漿怪類似,那肯定也要繼承史萊姆
public class EntitySnowCube extends EntitySlime {/* codes */ }??2.然后我們從巖漿怪的源碼里面拷一段給雪球怪
public class EntitySnowCube extends EntitySlime {public EntitySnowCube(World worldIn) {super(worldIn);}public void registerFixesSnowCube(DataFixer fixer) {EntityLiving.registerFixesMob(fixer, EntitySnowCube.class);}/*** 改變了了雪球怪的速度,讓他和巖漿怪一樣(這個方法是粘貼自巖漿怪的)*/@Overrideprotected void applyEntityAttributes() {super.applyEntityAttributes();this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);}/*** @return 設置是否能召喚,只要游戲難度不是和平模式就能召喚*/@Overridepublic boolean getCanSpawnHere() {return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;}/*** 這個方法依舊是粘貼的巖漿怪的,他的作用應該是用來設置史萊姆的大小的(大史萊姆,中史萊姆,小史萊姆)* 這個方法中顯示調用了超類史萊姆的方法設置好了大小,然后再把生物的護甲值升高,所以巖漿怪才會比普通史萊姆難打。* @param size* @param resetHealth*/@Overrideprotected void setSlimeSize(int size, boolean resetHealth){super.setSlimeSize(size, resetHealth);this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue((double)(size * 3));}/*** 跳躍延遲,直接粘貼巖漿怪的數據了*/@Overrideprotected int getJumpDelay(){return super.getJumpDelay() * 4;}/*** @return 能否傷害玩家* 這里和巖漿怪保持一致,無論大小都能傷害,但其實史萊姆這里是return !this.isSmallSlime();小的沒有攻擊力*/@Overrideprotected boolean canDamagePlayer(){return true;}/*** @return 攻擊強度,這里和巖漿怪保持一致,是史萊姆攻擊強度加二*/@Overrideprotected int getAttackStrength(){return super.getAttackStrength() + 2;}}??這樣雪球怪就擁有了一部分和巖漿怪一樣的屬性
??需要注意的是,巖漿怪的構造方法其實比史萊姆和雪球怪的多了一行。
public EntityMagmaCube(World worldIn){super(worldIn);this.isImmuneToFire = true;}??這多的一行是的巖漿怪可以免疫火焰,那我們的雪球怪自然要把這一行刪掉。
??3.設置一些不一樣的屬性:
/*** 該方法繼承自史萊姆* @return 設置的粒子效果*/@Overrideprotected EnumParticleTypes getParticleType() {return EnumParticleTypes.SNOWBALL;}/*** @return 這個返回值是雪球怪死后會分裂成什么*/@Overrideprotected EntitySlime createInstance(){return new EntitySnowCube(this.world);}/*** 這個方法是獲得掉落物表,繼承自EntityLiving* @return 返回掉落物表*/@Override@Nullableprotected ResourceLocation getLootTable(){// 如果是小史萊姆才會掉落雪球return this.isSmallSlime() ? LootTableList.ENTITIES_SNOWMAN : LootTableList.EMPTY;}/*** 被攻擊后發出的聲音* @return 這里和雪傀儡一致*/@Overrideprotected SoundEvent getHurtSound(DamageSource damageSourceIn){return SoundEvents.ENTITY_SNOWMAN_HURT;}/*** 死亡音效* @return 和雪傀儡一致*/@Overrideprotected SoundEvent getDeathSound(){return SoundEvents.ENTITY_SNOWMAN_DEATH;}/*** 被擠壓的音效* @return 雪傀儡沒有這個音效,所以這里用的是雪傀儡的環境音效*/@Overrideprotected SoundEvent getSquishSound(){return SoundEvents.ENTITY_SNOWMAN_AMBIENT;}/*** 跳躍音效* @return 使用扔雪球的音效*/protected SoundEvent getJumpSound(){return SoundEvents.ENTITY_SNOWBALL_THROW;}/** 此外還有幾個方法繼承自史萊姆* jump() handleJumpLava() handleJumpWater() 等,* 只知道是關于跳躍,其他具體情況就不知道了* 這里沒有拷貝巖漿球的數據,讓雪球怪跟史萊姆的這些數據保持一致好了*/??5.讓雪球怪具有一部分雪傀儡的屬性:
??首先我們翻閱雪傀儡的源碼,找到其中令雪傀儡走路留雪,見水死等屬性的方法:
public void onLivingUpdate(){super.onLivingUpdate();if (!this.world.isRemote){int i = MathHelper.floor(this.posX);int j = MathHelper.floor(this.posY);int k = MathHelper.floor(this.posZ);if (this.isWet()){this.attackEntityFrom(DamageSource.DROWN, 1.0F);}if (this.world.getBiome(new BlockPos(i, 0, k)).getTemperature(new BlockPos(i, j, k)) > 1.0F){this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F);}if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)){return;}for (int l = 0; l < 4; ++l){i = MathHelper.floor(this.posX + (double)((float)(l % 2 * 2 - 1) * 0.25F));j = MathHelper.floor(this.posY);k = MathHelper.floor(this.posZ + (double)((float)(l / 2 % 2 * 2 - 1) * 0.25F));BlockPos blockpos = new BlockPos(i, j, k);if (this.world.getBlockState(blockpos).getMaterial() == Material.AIR && this.world.getBiome(blockpos).getTemperature(blockpos) < 0.8F && Blocks.SNOW_LAYER.canPlaceBlockAt(this.world, blockpos)){this.world.setBlockState(blockpos, Blocks.SNOW_LAYER.getDefaultState());}}}}??顯而易見是這個,這個方法繼承自抽象類EntityLiving,而史萊姆也繼承自這個抽象類,所以我們完全可以讓雪球怪也繼承這個方法。
??6.完整的雪球怪代碼:
package com.darkill.examplemod.entity;import net.minecraft.block.material.Material; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.monster.EntitySlime; import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraft.util.datafix.DataFixer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; import net.minecraft.world.storage.loot.LootTableList;import javax.annotation.Nullable;public class EntitySnowCube extends EntitySlime {public EntitySnowCube(World worldIn) {super(worldIn);}public void registerFixesSnowCube(DataFixer fixer) {EntityLiving.registerFixesMob(fixer, EntitySnowCube.class);}/*** 改變了了雪球怪的速度,讓他和巖漿怪一樣(這個方法是粘貼自巖漿怪的)*/@Overrideprotected void applyEntityAttributes() {super.applyEntityAttributes();this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);}/*** @return 設置是否能召喚,只要游戲難度不是和平模式就能召喚*/@Overridepublic boolean getCanSpawnHere() {return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;}/*** 從雪傀儡的源碼中拷貝了一個函數給雪球怪* 使雪球怪擁有一些雪傀儡的屬性。*/@Overridepublic void onLivingUpdate(){super.onLivingUpdate();if (!this.world.isRemote){int i = MathHelper.floor(this.posX);int j = MathHelper.floor(this.posY);int k = MathHelper.floor(this.posZ);if (this.isWet()){this.attackEntityFrom(DamageSource.DROWN, 1.0F);}if (this.world.getBiome(new BlockPos(i, 0, k)).getTemperature(new BlockPos(i, j, k)) > 1.0F){this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F);}if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)){return;}for (int l = 0; l < 4; ++l){i = MathHelper.floor(this.posX + (double)((float)(l % 2 * 2 - 1) * 0.25F));j = MathHelper.floor(this.posY);k = MathHelper.floor(this.posZ + (double)((float)(l / 2 % 2 * 2 - 1) * 0.25F));BlockPos blockpos = new BlockPos(i, j, k);if (this.world.getBlockState(blockpos).getMaterial() == Material.AIR && this.world.getBiome(blockpos).getTemperature(blockpos) < 0.8F && Blocks.SNOW_LAYER.canPlaceBlockAt(this.world, blockpos)){this.world.setBlockState(blockpos, Blocks.SNOW_LAYER.getDefaultState());}}}}/*** 這個方法依舊是粘貼的巖漿怪的,他的作用應該是用來設置史萊姆的大小的(大史萊姆,中史萊姆,小史萊姆)* 這個方法中顯示調用了超類史萊姆的方法設置好了大小,然后再把生物的護甲值升高,所以巖漿怪才會比普通史萊姆難打。* @param size* @param resetHealth*/@Overrideprotected void setSlimeSize(int size, boolean resetHealth){super.setSlimeSize(size, resetHealth);this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue((double)(size * 3));}/*** 該方法繼承自史萊姆* @return 設置的粒子效果*/@Overrideprotected EnumParticleTypes getParticleType() {return EnumParticleTypes.SNOWBALL;}/*** @return 這個返回值是雪球怪死后會分裂成什么*/@Overrideprotected EntitySlime createInstance(){return new EntitySnowCube(this.world);}/*** 這個方法是獲得掉落物表,繼承自EntityLiving* @return 返回掉落物表*/@Override@Nullableprotected ResourceLocation getLootTable(){// 如果是小史萊姆才會掉落雪球return this.isSmallSlime() ? LootTableList.ENTITIES_SNOWMAN : LootTableList.EMPTY;}/*** 跳躍延遲,直接粘貼巖漿怪的數據了*/@Overrideprotected int getJumpDelay(){return super.getJumpDelay() * 4;}/** 此外還有幾個方法繼承自史萊姆* jump() handleJumpLava() handleJumpWater() 等,* 只知道是關于跳躍,其他具體情況就不知道了* 這里沒有拷貝巖漿球的數據,讓雪球怪跟史萊姆的這些數據保持一致好了*//*** @return 能否傷害玩家* 這里和巖漿怪保持一致,無論大小都能傷害,但其實史萊姆這里是return !this.isSmallSlime();小的沒有攻擊力*/@Overrideprotected boolean canDamagePlayer(){return true;}/*** @return 攻擊強度,這里和巖漿怪保持一致,是史萊姆攻擊強度加二*/@Overrideprotected int getAttackStrength(){return super.getAttackStrength() + 2;}/*** 被攻擊后發出的聲音* @return 這里和雪傀儡一致*/@Overrideprotected SoundEvent getHurtSound(DamageSource damageSourceIn){return SoundEvents.ENTITY_SNOWMAN_HURT;}/*** 死亡音效* @return 和雪傀儡一致*/@Overrideprotected SoundEvent getDeathSound(){return SoundEvents.ENTITY_SNOWMAN_DEATH;}/*** 被擠壓的音效* @return 雪傀儡沒有這個音效,所以這里用的是雪傀儡的環境音效*/@Overrideprotected SoundEvent getSquishSound(){return SoundEvents.ENTITY_SNOWMAN_AMBIENT;}/*** 跳躍音效* @return 使用扔雪球的音效*/protected SoundEvent getJumpSound(){return SoundEvents.ENTITY_SNOWBALL_THROW;}}三、加載雪球怪的材質
??做這一步時,我們需要下載兩個模組,tabula和iChunUtil,這個我在CSDN上上傳了,點這里下載tabula和iChunUtil。
??具體如何使用這兩個工具,并把模型導入項目,請參考b站的這個視頻
??然后做好材質以后我們就可以運行游戲了。下面是我做的材質:
四、運行游戲
??呆萌的材質
??能夠被雨淋死,還能留下雪跡:
??掉落物
總結
以上是生活随笔為你收集整理的【Minecraft java edition 模组开发】(二):通过对岩浆怪和雪傀儡的源码分析,自己制作一个雪球怪的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 物理层(网线)、数据链路层(交换机)、网
- 下一篇: 清华女硕士代言西湖名胜六和塔(组图),张