想在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模组开发(三十四) 自定义载具相关推荐

  1. Minecraft 1.16.5模组开发(三十二) 自定义投掷物品实体

    如果你了解过之前我们的实体开发教程,那么本次的教程会相对比较好理解. Minecraft 1.12.2模组开发(七) 实体(魔改Zombie) 我们本次将参考雪球在MC中制作一个属于我们自己的可投掷实 ...

  2. Minecraft 1.16.5模组开发(三十八) 3D盔甲(新)

    Minecraft升级到1.16.5后,3D盔甲的制作方法也跟之前版本稍有不同(主要在第二步.第四步),建议先复习一下往期教程: Minecraft 1.12.2模组开发(三十七) 3D盔甲 1.在b ...

  3. Minecraft 1.16.5模组开发(三十) 自定义成就系统(advancements)

    我们本次将尝试在模组中加入属于自己的成就系统 1.打开Minecraft成就生成制作网站进行成就的制作 我的世界成就系统制作网站 在data包下新建advancement文件夹 -> 在文件夹中 ...

  4. Minecraft 1.16.5模组开发(五十四) 方块探测器(Detector)

    我们本次预计实现一个方块探测器,让其可以探测我们想要找到的方块. 1.我们希望将方块放下后,可以探测以其坐标为中心的16×16×16的范围内是否具有目标方块: 新建一个方块类BlockBFS,为了方便 ...

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

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

  6. Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)

    如果你学习过我们之前在1.12.2的建筑生成教程,那么对本次的教程的理解可能会相对轻松. 往期回顾 Minecraft 1.12.2模组开发(十四) 建筑生成 (structure generatio ...

  7. Minecraft 1.16.5模组开发(五十) 书籍词典 (Guide Book)

    诸如冰与火之歌.深渊国度等模组,玩家往往可以通过使用模组中的参考书籍来达到快速上手的效果. 冰与火之歌异兽手记冰与火之歌异兽手记冰与火之歌异兽手记 我们今天在模组中实现一本模组参考书籍,方便其他玩家游 ...

  8. Minecraft 1.12.2模组开发(三十九) 反应器(TileEntity方块实体)

    说到方块实体(TileEntity),可以理解为一种功能性方块,比如熔炉,箱子,附魔台等. 我们今天来做一个类似于熔炉的反应器 熔炉逻辑: 放入燃料-> 放入物品 -> 获取产出物品 1. ...

  9. Minecraft 1.16.5模组开发(五十二) 修改原版生物战利品 (Loot Table)

    我们今天尝试对原版中的一些生物的掉落物进行修改 1.我们本次修改的是原版中Zombie的掉落物,所以我们需要找到原版Zombie的战利品表: zombie.json {"type" ...

最新文章

  1. mysql数据库多级分类汇总_sql多级分类汇总实现介绍
  2. 双 11 的狂欢,干了这碗「流量防控」汤
  3. 不是微型计算机主板上的部件,微型计算机主板上安装的主要部件
  4. C++ 中的类型限定符 类型限定符提供了变量的额外信息。
  5. 基于ECLIPSE的C++环境配置。。
  6. mysql in 原理_深入理解MySql子查询IN的执行和优化
  7. 单目视觉机器人的循迹_机器人视觉系统传感器的关键技术盘点
  8. Codeforces Testing Round #10 A. Forgotten Episode
  9. [NOI2009]管道取珠
  10. 腾讯获准在中国销售Switch游戏机 任天堂股价应声飙升逾14%
  11. python之路-基础篇-002
  12. Idea删除未引用包或暴红的包
  13. 移动web页面前端开发总结
  14. 一文教会你导出微信聊天记录
  15. file open error: [Errno 2] No such file or directory: '\xe6\xb5\x8b\xe8\xaf\x95.txt'
  16. 移动云计算的四大特点
  17. pandas || df.dropna() 缺失值删除
  18. 分享一份完整的软件系统测试方案,建议收藏
  19. 龙年新作:水印文字添加工具源码摘要
  20. 职场技巧:如何跟老板谈涨工资?

热门文章

  1. Linux驱动——sd type card(七)
  2. 解决Visual Studio C4996报错
  3. Matlab模拟登陆网页,转:使用matlab自动登录网站(人人网、新浪微博)代码
  4. 将12345转换为一万两千三百四十五
  5. 秋招 | 加入迪士尼!迪士尼全资在线视频子公司「hotstar」校招!
  6. 制作五彩纸屑转场动效_让它下雨五彩纸屑不要担心混乱
  7. 全球及中国再生纸屑行业研究及十四五规划分析报告
  8. hp ml110g7 linux,HP ML110 G7 安装2015操作系统.doc
  9. OpenJudge NOI 3.9 3341:Set
  10. Skia Viewer编译教程