Minecraft 1.16.5模组开发(三十四) 自定义载具

Minecraft 1.16.5模组开发(三十四) 自定义载具,第1张

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 WOOD_TYPE
//            = EntityDataManager.defineId(HeisenCarEntity.class, DataSerializers.STRING);

    public HeisenCarEntity(EntityType 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> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITIES,
            Utils.MOD_ID);
    
    //我们的车辆
        public static final RegistryObject> 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> 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> {

    public static final ResourceLocation TEXTURE = new ResourceLocation(Utils.MOD_ID, "textures/entity/heisenberg2.png");

    public RenderHeisenCar(EntityRendererManager manager) {
        super(manager, new ModelHeisenCar(), 0.7f);
    }

    @Override
    public 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;



@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");

    
     //将我们的载具渲染在这个函数中调用
    @SubscribeEvent
    public 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 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 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键位对载具 *** 控进行移动:

新年快乐!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686156.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存