Minecraft 1.16.5模组开发(三十四) 自定义载具
想在MC中开车吗?今天我们在MC中制作一辆车。
由于车辆是一个生物实体,所以要首先了解MC中的实体:我的世界实体教程
1.首先我们要制作一个车辆实体的模型(blockbench) 下载地址:
将模型导出(本教程在1.16.5下使用Mojmaps格式)
导数模型的.java文件:
将该文件文件放入开发包中
2.Entity包中新建一个汽车类HeisenCarEntity.java:
我们的汽车默认以马类为父类,但取消了马年龄和可驯服的特征,使其更加符合一个载具的设定:
package com.joy187.re8joymod.common.entity;import com.joy187.re8joymod.common.init.EntityInit;
import com.joy187.re8joymod.common.init.ModItems;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
import net.minecraft.entity.ai.attributes.Attributes;
import net.minecraft.entity.ai.goal.*;
import net.minecraft.entity.item.BoatEntity;
import net.minecraft.entity.passive.PigEntity;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.entity.passive.horse.HorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.network.IPacket;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.potion.Effects;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
//继承马类生物
public class HeisenCarEntity extends HorseEntity {// private static final DataParameter<String> WOOD_TYPE
// = EntityDataManager.defineId(HeisenCarEntity.class, DataSerializers.STRING);public HeisenCarEntity(EntityType<? extends HeisenCarEntity> p_i50250_1_, World p_i50250_2_) {super(p_i50250_1_, p_i50250_2_);}// public HeisenCarEntity(World worldIn, double x, double y, double z) {
// //this(EntityInit.HEISENCAR.get(), worldIn);
// this.setPos(x, y, z);
// this.setDeltaMovement(Vector3d.ZERO);
// this.xo = x;
// this.yo = y;
// this.zo = z;
// }public void aiStep() {super.aiStep();}protected void registerGoals() {this.goalSelector.addGoal(7, new LookAtGoal(this, PlayerEntity.class, 6.0F));this.addBehaviourGoals();}//设置车辆的相关属性,如生命值、移动速度等public static AttributeModifierMap.MutableAttribute setAttributes() {return MobEntity.createMobAttributes().add(Attributes.MAX_HEALTH, 100.0D).add(Attributes.MOVEMENT_SPEED, 0.4D);}public boolean canBeControlledByRider() {Entity entity = this.getControllingPassenger();if (!(entity instanceof PlayerEntity)) {return false;} else {//可直接被玩家骑乘,无需驯服PlayerEntity playerentity = (PlayerEntity)entity;return true;}}public ActionResultType mobInteract(PlayerEntity p_230254_1_, Hand p_230254_2_) {this.doPlayerRide(p_230254_1_);return ActionResultType.sidedSuccess(this.level.isClientSide);}//该函数是开车时的速度等控制,可以自行调整public void travel(Vector3d p_213352_1_) {if (this.isAlive()) {if (this.isVehicle() && this.canBeControlledByRider()) {LivingEntity livingentity = (LivingEntity)this.getControllingPassenger();this.yRot = livingentity.yRot;this.yRotO = this.yRot;this.xRot = livingentity.xRot * 0.5F;this.setRot(this.yRot, this.xRot);this.yBodyRot = this.yRot;this.yHeadRot = this.yBodyRot;float f = livingentity.xxa * 0.5F;float f1 = livingentity.zza;if (f1 <= 0.0F) {f1 *= 0.25F;this.gallopSoundCounter = 0;}if (this.onGround && this.playerJumpPendingScale == 0.0F && this.isStanding()) {f = 0.0F;f1 = 0.0F;}if (this.playerJumpPendingScale > 0.0F && !this.isJumping() && this.onGround) {double d0 = this.getCustomJump() * (double)this.playerJumpPendingScale * (double)this.getBlockJumpFactor();double d1;if (this.hasEffect(Effects.JUMP)) {d1 = d0 + (double)((float)(this.getEffect(Effects.JUMP).getAmplifier() + 1) * 0.1F);} else {d1 = d0;}Vector3d vector3d = this.getDeltaMovement();this.setDeltaMovement(vector3d.x, d1, vector3d.z);this.setIsJumping(true);this.hasImpulse = true;net.minecraftforge.common.ForgeHooks.onLivingJump(this);if (f1 > 0.0F) {float f2 = MathHelper.sin(this.yRot * ((float)Math.PI / 180F));float f3 = MathHelper.cos(this.yRot * ((float)Math.PI / 180F));this.setDeltaMovement(this.getDeltaMovement().add((double)(-0.4F * f2 * this.playerJumpPendingScale), 0.0D, (double)(0.4F * f3 * this.playerJumpPendingScale)));}this.playerJumpPendingScale = 0.0F;}this.flyingSpeed = this.getSpeed() * 0.1F;if (this.isControlledByLocalInstance()) {this.setSpeed((float)this.getAttributeValue(Attributes.MOVEMENT_SPEED));super.travel(new Vector3d((double)f, p_213352_1_.y, (double)f1));} else if (livingentity instanceof PlayerEntity) {this.setDeltaMovement(Vector3d.ZERO);}if (this.onGround) {this.playerJumpPendingScale = 0.0F;this.setIsJumping(false);}this.calculateEntityAnimation(this, false);} else {this.flyingSpeed = 0.02F;super.travel(p_213352_1_);}}}public float getSteeringSpeed() {return (float)this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.15F;}}
新建一个EntityInit.java,将我们刚刚设定好的车辆在这个类中统一放置:
package com.joy187.re8joymod.common.init;import com.joy187.re8joymod.Utils;
import com.joy187.re8joymod.common.entity.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.PigEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.entity.projectile.SpectralArrowEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;public class EntityInit {public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITIES,Utils.MOD_ID);//我们的车辆public static final RegistryObject<EntityType<HeisenCarEntity>> HEISENCAR = ENTITY_TYPES.register("heisencar",() -> EntityType.Builder.of(HeisenCarEntity::new, EntityClassification.MISC).sized(2f,0.8f).setTrackingRange(30).build(new ResourceLocation(Utils.MOD_ID, "heisencar").toString())); //其他的生物实体也在这里// public static final RegistryObject<EntityType<EntityRose>> ROSE = ENTITY_TYPES.register("rose",
// () -> EntityType.Builder.of(EntityRose::new, EntityClassification.MONSTER).sized(2f,0.8f).setTrackingRange(30)
// .build(new ResourceLocation(Utils.MOD_ID, "rose").toString()));}
3.新建一个渲染类RenderHeisenCar.java用于车辆在游戏中的模型渲染:
package com.joy187.re8joymod.common.entity.render;import com.joy187.re8joymod.Utils;
import com.joy187.re8joymod.common.entity.HeisenCarEntity;
import com.joy187.re8joymod.common.entity.model.ModelHeisenCar;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.client.renderer.entity.MobRenderer;
import net.minecraft.util.ResourceLocation;public class RenderHeisenCar extends MobRenderer<HeisenCarEntity, ModelHeisenCar<HeisenCarEntity>> {public static final ResourceLocation TEXTURE = new ResourceLocation(Utils.MOD_ID, "textures/entity/heisenberg2.png");public RenderHeisenCar(EntityRendererManager manager) {super(manager, new ModelHeisenCar<HeisenCarEntity>(), 0.7f);}@Overridepublic ResourceLocation getTextureLocation(HeisenCarEntity p_110775_1_) {return TEXTURE;}}
新建一个ClientModEventSubscriber.java文件用于对渲染文件进行处理
package com.joy187.re8joymod.common;import com.joy187.re8joymod.Utils;
import com.joy187.re8joymod.common.entity.render.*;
import com.joy187.re8joymod.common.init.EntityInit;
import com.joy187.re8joymod.common.init.ModItems;
import com.joy187.re8joymod.common.items.ItemGM79B;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.SpriteRenderer;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import net.minecraft.client.gui.ScreenManager;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;/*** Subscribe to events from the MOD EventBus that should be handled on the PHYSICAL CLIENT side in this class** @author Sinhika*/
@EventBusSubscriber(modid= Utils.MOD_ID, bus=EventBusSubscriber.Bus.MOD, value=Dist.CLIENT)
public class ClientModEventSubscriber
{private static final Logger LOGGER = LogManager.getLogger(Utils.MOD_ID + " Client Mod Event Subscriber");/*** We need to register our renderers on the client because rendering code does not exist on the server* and trying to use it on a dedicated server will crash the game.* <p>* This method will be called by Forge when it is time for the mod to do its client-side setup* This method will always be called after the Registry events.* This means that all Blocks, Items, TileEntityTypes, etc. will all have been registered already*///将我们的载具渲染在这个函数中调用@SubscribeEventpublic static void onFMLClientSetupEvent(final FMLClientSetupEvent event){RenderingRegistry.registerEntityRenderingHandler(EntityInit.HEISENCAR.get(), RenderHeisenCar::new);}} // end class
4.在我们的Main.java中的setup函数中添加实体的属性信息:
private void setup(final FMLCommonSetupEvent event) {DeferredWorkQueue.runLater(() -> GlobalEntityTypeAttributes.put(EntityInit.HEISENCAR.get(), HeisenCarEntity.setAttributes().build()));}
5.在.lang文件中添加我们的物品名称信息,将贴图放入textures/entity文件夹:
"entity.re8joymod.heisencar": "Heisen Car",
6.我们同时设计一个召唤载具的物品,物品具体教程可参照物品教程:
新建一个ItemVehicleCore.java文件用于召唤载具
package com.joy187.re8joymod.common.items;import com.joy187.re8joymod.common.entity.EntityDoll1;
import com.joy187.re8joymod.common.entity.EntityGM79B;
import com.joy187.re8joymod.common.entity.HeisenCarEntity;
import com.joy187.re8joymod.common.init.EntityInit;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.IItemTier;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;import java.util.Random;public class ItemVehicleCore extends ItemPickaxe {public ItemVehicleCore(IItemTier toolMaterial, int attackDamage, float attackSpeed, Properties itemProperties) {super(toolMaterial,attackDamage, attackSpeed, itemProperties);}@Override //这里我们设置按右键就可以召唤我们的载具public ActionResult<ItemStack> use(World p_77659_1_, PlayerEntity p_77659_2_, Hand p_77659_3_) {ItemStack itemstack = p_77659_2_.getItemInHand(p_77659_3_);//生成我们的载具HeisenCarEntity e = new HeisenCarEntity(EntityInit.HEISENCAR.get(), p_77659_2_.level);e.setPos(p_77659_2_.position().x,p_77659_2_.position().y,p_77659_2_.position().z);p_77659_2_.level.addFreshEntity(e);if (!p_77659_2_.abilities.instabuild) {itemstack.shrink(10000);if (itemstack.isEmpty()) {p_77659_2_.inventory.removeItem(itemstack);}}return ActionResult.success(itemstack);}}
在ItemInit中声明该物品:
public static final RegistryObject<ItemPickaxe> HCKEY = ITEMS.register("vehicle_core",() -> new ItemVehicleCore(CustomItemTier.TOOL_KEY3,2,-1.5F,new Item.Properties().tab(RegistryEvents.RE8GROUP)));
在.lang文件添加该物品的名称,在models/item中新建该物品.json文件,绑定其贴图路径,贴图放入textures/items文件夹中:
en_us.lang
"item.re8joymod.vehicle_core":"Heisen Car Control",
vehicle_core.json
{"parent": "item/generated","textures": {"layer0": "re8joymod:items/factoryg" //和你在textures/items中的名称保持一致}
}
7.OK,载具和召唤物都制作完成,进入游戏进行测试:
可以按WASD键位对载具操控进行移动:
新年快乐!!!
Minecraft 1.16.5模组开发(三十四) 自定义载具相关推荐
- Minecraft 1.16.5模组开发(三十二) 自定义投掷物品实体
如果你了解过之前我们的实体开发教程,那么本次的教程会相对比较好理解. Minecraft 1.12.2模组开发(七) 实体(魔改Zombie) 我们本次将参考雪球在MC中制作一个属于我们自己的可投掷实 ...
- Minecraft 1.16.5模组开发(三十八) 3D盔甲(新)
Minecraft升级到1.16.5后,3D盔甲的制作方法也跟之前版本稍有不同(主要在第二步.第四步),建议先复习一下往期教程: Minecraft 1.12.2模组开发(三十七) 3D盔甲 1.在b ...
- Minecraft 1.16.5模组开发(三十) 自定义成就系统(advancements)
我们本次将尝试在模组中加入属于自己的成就系统 1.打开Minecraft成就生成制作网站进行成就的制作 我的世界成就系统制作网站 在data包下新建advancement文件夹 -> 在文件夹中 ...
- Minecraft 1.16.5模组开发(五十四) 方块探测器(Detector)
我们本次预计实现一个方块探测器,让其可以探测我们想要找到的方块. 1.我们希望将方块放下后,可以探测以其坐标为中心的16×16×16的范围内是否具有目标方块: 新建一个方块类BlockBFS,为了方便 ...
- Minecraft 1.16.5模组开发(二十八) 自定义生态群系(biome)
今天我们尝试在MC中制作一个属于自己的生态群系 1.进入网站,选择Worldgen->Biome Generator进行空间维度的设定与制作: Minecraft 1.15,1.16,1.17自 ...
- Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)
如果你学习过我们之前在1.12.2的建筑生成教程,那么对本次的教程的理解可能会相对轻松. 往期回顾 Minecraft 1.12.2模组开发(十四) 建筑生成 (structure generatio ...
- Minecraft 1.16.5模组开发(五十) 书籍词典 (Guide Book)
诸如冰与火之歌.深渊国度等模组,玩家往往可以通过使用模组中的参考书籍来达到快速上手的效果. 冰与火之歌异兽手记冰与火之歌异兽手记冰与火之歌异兽手记 我们今天在模组中实现一本模组参考书籍,方便其他玩家游 ...
- Minecraft 1.12.2模组开发(三十九) 反应器(TileEntity方块实体)
说到方块实体(TileEntity),可以理解为一种功能性方块,比如熔炉,箱子,附魔台等. 我们今天来做一个类似于熔炉的反应器 熔炉逻辑: 放入燃料-> 放入物品 -> 获取产出物品 1. ...
- Minecraft 1.16.5模组开发(五十二) 修改原版生物战利品 (Loot Table)
我们今天尝试对原版中的一些生物的掉落物进行修改 1.我们本次修改的是原版中Zombie的掉落物,所以我们需要找到原版Zombie的战利品表: zombie.json {"type" ...
最新文章
- mysql数据库多级分类汇总_sql多级分类汇总实现介绍
- 双 11 的狂欢,干了这碗「流量防控」汤
- 不是微型计算机主板上的部件,微型计算机主板上安装的主要部件
- C++ 中的类型限定符 类型限定符提供了变量的额外信息。
- 基于ECLIPSE的C++环境配置。。
- mysql in 原理_深入理解MySql子查询IN的执行和优化
- 单目视觉机器人的循迹_机器人视觉系统传感器的关键技术盘点
- Codeforces Testing Round #10 A. Forgotten Episode
- [NOI2009]管道取珠
- 腾讯获准在中国销售Switch游戏机 任天堂股价应声飙升逾14%
- python之路-基础篇-002
- Idea删除未引用包或暴红的包
- 移动web页面前端开发总结
- 一文教会你导出微信聊天记录
- file open error: [Errno 2] No such file or directory: '\xe6\xb5\x8b\xe8\xaf\x95.txt'
- 移动云计算的四大特点
- pandas || df.dropna() 缺失值删除
- 分享一份完整的软件系统测试方案,建议收藏
- 龙年新作:水印文字添加工具源码摘要
- 职场技巧:如何跟老板谈涨工资?
热门文章
- Linux驱动——sd type card(七)
- 解决Visual Studio C4996报错
- Matlab模拟登陆网页,转:使用matlab自动登录网站(人人网、新浪微博)代码
- 将12345转换为一万两千三百四十五
- 秋招 | 加入迪士尼!迪士尼全资在线视频子公司「hotstar」校招!
- 制作五彩纸屑转场动效_让它下雨五彩纸屑不要担心混乱
- 全球及中国再生纸屑行业研究及十四五规划分析报告
- hp ml110g7 linux,HP ML110 G7 安装2015操作系统.doc
- OpenJudge NOI 3.9 3341:Set
- Skia Viewer编译教程