You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Minecraft自定义药水效果开发问题:时效结束触发其他效果报错

解决Minecraft药水时效结束后触发后续效果的问题

首先,你当前的思路有个关键偏差:performEffect方法是每游戏刻(tick)都会执行一次的,它的作用是处理药水持续生效期间的周期性逻辑,根本不是检测效果结束的正确时机。要实现“时效结束后自动施加其他药水效果”,你应该重写Potion类的onPotionRemove方法——这个方法会在药水效果从玩家身上移除时(包括时间自然耗尽、被牛奶清除等情况)触发。

正确实现步骤

1. 核心:重写onPotionRemove方法

在你的自定义药水类(比如PotionBuzz)中,添加这个方法来处理效果结束后的逻辑:

@Override
public void onPotionRemove(EntityLivingBase entity, int amplifier) {
    // 先确保目标是玩家实体
    if (entity instanceof EntityPlayer) {
        EntityPlayer player = (EntityPlayer) entity;
        // 施加你需要的后续药水效果,这里以跳跃提升为例
        // 参数说明:效果实例、持续时间(20tick=1秒)、 amplifier(效果等级-1)
        player.addPotionEffect(new PotionEffect(PotionRegistry.JUMP_BOOST, 300, amplifier));
    }
}

2. 清理冗余的performEffect逻辑

你之前在performEffect里判断玩家是否持有该效果是完全多余的——因为performEffect只有当玩家身上存在这个药水效果时才会被调用。如果你的药水在持续期间不需要任何周期性操作,直接把这个方法留空即可:

@Override
public void performEffect(EntityLivingBase entity, int amplifier) {
    // 持续期间无操作,留空
}

3. 进阶:只在时效自然结束时触发

如果想区分“时效自然耗尽”和“被手动清除(比如喝牛奶)”两种情况,可以额外判断药水剩余时间:

@Override
public void onPotionRemove(EntityLivingBase entity, int amplifier) {
    if (entity instanceof EntityPlayer) {
        EntityPlayer player = (EntityPlayer) entity;
        PotionEffect activeEffect = player.getActivePotionEffect(this);
        // 只有当剩余时间为0时,才判定为自然结束
        if (activeEffect != null && activeEffect.getDuration() == 0) {
            player.addPotionEffect(new PotionEffect(PotionRegistry.SPEED, 200, amplifier));
        }
    }
}

完整自定义药水类示例

public class PotionBuzz extends Potion {
    public PotionBuzz() {
        // 构造参数:是否为负面效果、药水颜色、注册名(1.13+版本用Registry)
        super(false, 0xFFD700);
        setRegistryName("buzz");
        setPotionName("effect.buzz");
    }

    // 效果结束时触发的逻辑
    @Override
    public void onPotionRemove(EntityLivingBase entity, int amplifier) {
        if (entity instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) entity;
            // 替换成你需要的后续效果
            player.addPotionEffect(new PotionEffect(PotionRegistry.JUMP_BOOST, 300, amplifier));
        }
    }

    // 持续期间无操作,留空
    @Override
    public void performEffect(EntityLivingBase entity, int amplifier) {}
}

内容的提问来源于stack exchange,提问作者Jarrod Muddyman

火山引擎 最新活动