Flandre923
822 words
4 minutes
03 实体爆炸雪球

03 实体爆炸雪球#

/**
 * TNTProjectileEntity 类继承自 ThrowableItemProjectile,代表一个 TNT 弹射物实体
 * 该类负责处理 TNT 弹射物的创建、移动以及爆炸行为
 */
public class TNTProjectileEntity extends ThrowableItemProjectile {

    /**
     * 构造函数,用于创建 TNT 弹射物实体
     * @param entityType 实体类型,用于确定该实体的基本属性和行为
     * @param level 代表 Minecraft 世界,用于实体与游戏世界的交互
     */
    public TNTProjectileEntity(EntityType<? extends ThrowableItemProjectile> entityType, Level level) {
        super(entityType, level);
    }

    /**
     * 构造函数,用于由生物发射 TNT 弹射物实体
     * @param livingEntity 射手实体,用于确定弹射物的初始位置和方向
     * @param world 代表 Minecraft 世界,用于实体与游戏世界的交互
     */
    public TNTProjectileEntity(LivingEntity livingEntity, Level world){
        super(ModEntities.TNT_PROJECTILE.get(),livingEntity,world);
    }

    /**
     * 获取默认的物品
     * @return 返回代表 TNT 弹的物品
     */
    @Override
    protected Item getDefaultItem() {
        return ModItems.TNT_BALL.get();
    }

    /**
     * 当弹射物击中方块时的行为
     * 在服务端触发爆炸效果,并生成火焰粒子效果
     * @param result 包含击中位置和方向的 BlockHitResult 对象
     */
    @Override
    protected void onHitBlock(BlockHitResult result) {

        if(!this.level().isClientSide()) {
//            this.level().sendEntityStatus(this, (byte)3);
            explode();
            CustomParticleRenderer.spawnFlameParticles(result.getLocation());
        }

        this.discard();
        super.onHitBlock(result);
    }

    /**
     * 当弹射物击中实体时的行为
     * 该方法目前未实现具体行为,通过调用父类方法处理
     * @param result 包含击中实体和位置的 EntityHitResult 对象
     */
    @Override
    protected void onHitEntity(EntityHitResult result) {
        super.onHitEntity(result);
    }

    /**
     * 使弹射物发生爆炸
     * 在弹射物所在位置生成爆炸效果,影响周围环境
     */
    private void explode(){
        float f = 4.0F;
        this.level().explode(this,this.getX(),this.getY(0.0625),this.getZ(),f,Level.ExplosionInteraction.TNT);
    }
}

public class StoneBallProjectileEntity extends ThrowableItemProjectile {
    public StoneBallProjectileEntity(EntityType<? extends StoneBallProjectileEntity> entityType, Level world) {
        super(entityType, world);
    }

    public StoneBallProjectileEntity(LivingEntity livingEntity, Level world) {
        super(ModEntities.STONE_PROJECTILE.get(), livingEntity, world);
    }

    @Override
    protected Item getDefaultItem() {
        return ModItems.STONE_BALL.get();
    }

    @Override
    protected void onHitEntity(EntityHitResult result) {
        if (!this.level().isClientSide){ // 使敌人受伤,并移除自身。
            Entity entity = result.getEntity();
            Entity owner = this.getOwner();
            entity.hurt(this.damageSources().thrown(this,owner),6f);
            if (entity instanceof LivingEntity){
                // todo enchantment effect
            }
            this.discard();
        }
    }
}

注册

import net.neoforged.neoforge.registries.DeferredRegister;

public class ModEntities {
    // 使用DeferredRegister创建一个延迟注册的实体类型列表,用于在Minecraft游戏中注册自定义实体
    public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(Registries.ENTITY_TYPE, NeoMafishMod.MODID);

    // 注册一种实体类型,代表游戏中的一种TNT射出的实体
    public static final DeferredHolder<EntityType<?>,EntityType<TNTProjectileEntity>> TNT_PROJECTILE = ENTITY_TYPES.register("tnt_projectile",
            ()-> EntityType.Builder.<TNTProjectileEntity>of(TNTProjectileEntity::new, MobCategory.MISC).sized(0.25f,0.25f).build("tnt_projectile"));

    // 注册一种实体类型,代表游戏中的一种石球射出的实体
    public static final DeferredHolder<EntityType<?>,EntityType<StoneBallProjectileEntity>> STONE_PROJECTILE = ENTITY_TYPES.register("stone_projectile",
            ()-> EntityType.Builder.<StoneBallProjectileEntity>of(StoneBallProjectileEntity::new, MobCategory.MISC).sized(0.25f,0.25f).build("stone_projectile"));


    // 将自定义实体类型注册到事件总线,以便在游戏启动时自动注册这些实体类型
    public static void register(IEventBus eventBus){
        ENTITY_TYPES.register(eventBus);
    }

}

每一个EntityType都应该对应一个EntityRenderer​用于渲染对应的实体,我们这里直接用原版的ThrownItemRenderer​,这个renderer将会使用物品的纹理作为渲染。

@EventBusSubscriber(modid = NeoMafishMod.MODID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class ClientSetUp {

    @SubscribeEvent
    public static void rendererRegister(EntityRenderersEvent.RegisterRenderers event)
    {
        event.registerEntityRenderer(ModEntities.TNT_PROJECTILE.get(),ThrownItemRenderer::new);
        event.registerEntityRenderer(ModEntities.STONE_PROJECTILE.get(),ThrownItemRenderer::new);
    }
}

注册到总线

// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(NeoMafishMod.MODID)
public class NeoMafishMod
{
    // Define mod id in a common place for everything to reference
    public static final String MODID = "neomafishmod";
    private static final Logger LOGGER = LogUtils.getLogger();
    public NeoMafishMod(IEventBus modEventBus, ModContainer modContainer)
    {

        ModItems.ITEMS.register(modEventBus); // 物品 
        ModTabs.CREATIVE_TABS.register(modEventBus); // 创造模式物品栏
        ModEntities.register(modEventBus); // 实体

    }
}

添加对应的物品

    public static final DeferredItem<Item>  TNT_BALL = registerItem("tnt_ball", ()-> new TNTBallItem(new Item.Properties()));
    public static final DeferredItem<Item>  STONE_BALL = registerItem("stone_ball", ()-> new StoneBallItem(new Item.Properties()));

添加到创造模式物品栏,以及模型文件和贴图纹理就自己去添加吧。不会的话就看上期的之前的视频。

03 实体爆炸雪球
https://fuwari.vercel.app/posts/minecraft1_21_0/03_实体爆炸雪球/
Author
Flandre923
Published at
2024-08-24