You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minecraft 1.12.2 Forge模组RageMode触发后游戏无响应求助

Minecraft 1.12.2 Forge模组狂暴模式冻结问题修复

问题根源

按下U键后游戏冻结的核心原因是RageMode类的activateRage()方法使用了while循环阻塞主线程。Minecraft的游戏逻辑运行在单线程中,这个循环会持续占用线程资源,导致游戏无法处理任何输入、渲染或其他事件,最终界面完全卡死,只能强制关闭。

修复方案

改用Forge的Tick事件系统逐帧处理狂暴模式的逻辑,避免阻塞主线程。具体修改如下:

1. 修改RageMode类

将原有的阻塞式循环改为监听玩家Tick事件,分帧执行移动、攻击和破障逻辑,并在持续时间结束后自动注销事件监听:

package daun.aut.utils;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;

public class RageMode {

    private final EntityPlayer player;
    private final World world;
    private final long startTime;
    private final long duration = 10 * 20; // 10秒(20 Tick/秒)
    private final double speed = 1.5; // 移动速度

    public RageMode(EntityPlayer player) {
        this.player = player;
        this.world = player.world;
        this.startTime = world.getTotalWorldTime();
        MinecraftForge.EVENT_BUS.register(this);
    }

    @SubscribeEvent
    public void onPlayerTick(TickEvent.PlayerTickEvent event) {
        if (event.player != this.player || event.phase != TickEvent.Phase.END) {
            return;
        }

        if (world.getTotalWorldTime() >= startTime + duration) {
            MinecraftForge.EVENT_BUS.unregister(this);
            return;
        }

        EntityLivingBase target = findNearestTarget();
        if (target != null && !target.isDead) {
            moveTowards(target);
            attack(target);
            breakObstacles();
        }
    }

    private EntityLivingBase findNearestTarget() {
        return world.getNearestAttackableEntity(EntityLivingBase.class, player.getPositionVector(), 50.0,
                50.0, entity -> entity != player && entity.isEntityAlive() && player.canAttackEntity(entity));
    }

    private void moveTowards(EntityLivingBase target) {
        Vec3d playerPos = player.getPositionVector();
        Vec3d targetPos = target.getPositionVector().add(0, target.getEyeHeight() / 2, 0);
        Vec3d direction = targetPos.subtract(playerPos).normalize();
        Vec3d newPos = playerPos.add(direction.scale(speed / 20.0));

        player.setPositionAndUpdate(newPos.x, newPos.y, newPos.z);
    }

    private void attack(EntityLivingBase target) {
        if (world.getTotalWorldTime() % 20 == 0) {
            target.attackEntityFrom(DamageSource.causePlayerDamage(player), 200.0f);
        }
    }

    private void breakObstacles() {
        Vec3d playerPos = player.getPositionVector();
        Vec3d lookVec = player.getLookVec().normalize();
        for (int i = 1; i <= 3; i++) {
            BlockPos blockPos = new BlockPos(playerPos.add(lookVec.scale(i)));
            if (!world.isAirBlock(blockPos) && world.getBlockState(blockPos).getBlockHardness(world, blockPos) != -1) {
                world.destroyBlock(blockPos, true);
            }
        }
    }
}

2. 修改KeyInputHandler类

添加状态标记,防止玩家重复按下U键触发多次狂暴模式:

package daun.aut.utils.Handlers;

import daun.aut.utils.RageMode;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import org.lwjgl.input.Keyboard;

public class KeyInputHandler {

    private static final KeyBinding rageKey = new KeyBinding("key.ragemode", Keyboard.KEY_U, "key.categories.gameplay");
    private static boolean isRageActive = false;

    public static void registerKeyBindings() {
        ClientRegistry.registerKeyBinding(rageKey);
    }

    @SubscribeEvent
    public void onKeyInput(InputEvent.KeyInputEvent event) {
        if (rageKey.isPressed()) {
            EntityPlayer player = Minecraft.getMinecraft().player;
            if (player != null && !isRageActive) {
                new RageMode(player);
                isRageActive = true;
                Minecraft.getMinecraft().addScheduledTask(() -> isRageActive = false);
            }
        }
    }
}

3. Main类无需修改

原Main类的事件注册逻辑已经正确,保持不变即可。

修复要点说明

  • 移除阻塞循环:用Tick事件替代while循环,让游戏主线程能正常处理其他任务。
  • 事件生命周期管理:RageMode实例创建时注册到事件总线,结束后自动注销,避免内存泄漏。
  • 优化目标查找:支持攻击所有可攻击生物,不局限于玩家。
  • 控制攻击频率:每1秒攻击一次,避免瞬间秒杀目标的不合理情况。
  • 增强破障效果:检查玩家前方3格内的方块,提升路径清理能力。
  • 防止重复触发:用isRageActive标记避免多次激活狂暴模式。

内容的提问来源于stack exchange,提问作者Ego Solus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:24:52