零、什么是实体

  实体(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 模组开发】(二):通过对岩浆怪和雪傀儡的源码分析,自己制作一个雪球怪相关推荐

  1. 【Minecraft java edition 模组开发】(一):实现一个简单的模组

    零.写在前面 1.看这个系列需要什么前提? ① 对Minecraft有一定的了解,知道模组.方块.物品.实体等名词的具体含义. ② 对java编程有一定了解,至少要学到容器. ③ 会编写json代码, ...

  2. Minecraft 1.12.2模组开发(二十) 导出模组

    模组制作完成后,我们就可以将其导出成为.jar文件,进行发布,供全世界的玩家进行下载游玩了 1.进入模组开发的文件夹 -> 起动cmd控制台 2.输入构建指令等待其构建模组 Windows系统: ...

  3. Java Review - 线程池中使用ThreadLocal不当导致的内存泄漏案例源码分析

    文章目录 概述 Why 内存泄露 ? 在线程池中使用ThreadLocal导致的内存泄漏 概述 ThreadLocal的基本使用我们就不赘述了,可以参考 每日一博 - ThreadLocal VS I ...

  4. 移动端开发基本知识之touch.js,FastClick.js源码分析

    问题1:300ms延迟问题指的是? 不管在移动端还是PC端,我们都需要处理用户点击,这个最常用的事件.但在touch端click事件响应速度会比较慢,在较老的手机设备上会更为明显(300ms的延迟). ...

  5. Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析

    本章内容会针对比原官方提供的dapp-demo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案. 储蓄分红合约简述 为了方便理解,这里简 ...

  6. Minecraft 1.16.5模组开发(二十八) 自定义生态群系(biome)

    今天我们尝试在MC中制作一个属于自己的生态群系 1.进入网站,选择Worldgen->Biome Generator进行空间维度的设定与制作: Minecraft 1.15,1.16,1.17自 ...

  7. 服务网关zuul之二:过滤器--请求过滤执行过程(源码分析)

    Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求. 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生成 ...

  8. Minecraft 1.12.2模组开发(二十三) 霰弹枪!

    我们今天在世界中创造一把属于自己的霰弹枪 1.制作枪械和子弹的模型(blockbench) 下载地址 注意调整武器的手中方位(每个槽位都要调!) 2.在ModItems中添加我们刚刚制作的两个物品的信 ...

  9. java如何通过grpc连接etcd_grpc通过 etcd 实现服务发现与注册-源码分析

    介绍 下面介绍 jupiter-0.2.7 版本中 grpc 通过 etcd 实现服务发现与注册. 服务发现与注册的实现解析 服务注册 服务注册的流程图: etcd的服务注册代码模块在 jupiter ...

最新文章

  1. HTML5+MUI+HBuilder 之初探情人
  2. 51nod 1138 连续整数的和(数学公式)
  3. ITK:仅将过滤器应用于图像的指定区域
  4. 一站式 Java Web 框架 firefly-2.0_07发布
  5. 动手造轮子:实现简单的 EventQueue
  6. UVA 1645 - Count(简单DP)
  7. 65种GPU性能测试,AMD开源驱动领先!
  8. 某娱乐资源网同款网站源码
  9. Kafka概念和基本架构概述
  10. qt值qml制作足球动画(参考qmlbook)
  11. 呼和浩特市啥时计算机考试,2021上半年内蒙古自治区呼和浩特市全国计算机等级考试时间...
  12. 新手入门fedora9 如何打开终端
  13. andriod驱动之旅-a31s芯片-android环境
  14. 程序化生成(PCG)算法的改进——基于以地学为主的多基础学科
  15. python画小树_如何用Python画一颗小树?
  16. 利用计算机程序快速得到9*9大小数独的解法
  17. 微软认证全国考试中心一览表
  18. 生物化学 药物设计与研发笔记:变构(Allostery)药物设计
  19. 鸿蒙系统需要备份,华为鸿蒙系统正式发布之后,还需要面临三个问题
  20. MIC(最大信息系数)

热门文章

  1. C#几种读取文件的方式
  2. 火红色枫叶背景《你好秋天》秋分节气 PPT模板
  3. Java字节码角度分析:Synchronized ——提升硬实力11
  4. 微信小程序-视频弹幕的项目
  5. 轻论坛StartBBS、YouBBS、Xiuno对比
  6. 能耗在线监测系统在酒店节能管理中的应用
  7. 查看电脑ip地址是否被占用
  8. openCV教程01
  9. java 判断手机运营商_如何用java判断手机号运营商?
  10. 基于https搭建habor私有库