Flandre923
887 words
4 minutes
12 获取玩家是否按了某个键

12 获取玩家是否按了某个键#

这里以空格键和攻击键为例子

package com.mafuyu33.neomafishmod.event;

import com.mafuyu33.neomafishmod.NeoMafishMod;
import com.mafuyu33.neomafishmod.mixinhelper.BowDashMixinHelper;
import com.mafuyu33.neomafishmod.mixinhelper.ElytraJumpMixinHelper;
import com.mafuyu33.neomafishmod.mixinhelper.ShieldDashMixinHelper;
import net.minecraft.client.Minecraft;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientTickEvent;

@EventBusSubscriber(modid = NeoMafishMod.MODID, bus = EventBusSubscriber.Bus.GAME,value = Dist.CLIENT)
public class AttackKeyCheckHandler {
    // 获取 MinecraftClient 实例
//    private static final MinecraftClient client = MinecraftClient.getInstance();
//
//    // 获取 MinecraftClient 中的攻击键绑定
//    private static final KeyBinding attackKeyBinding = client.options.attackKey;
    private static boolean wasKeyPressedLastFrame = false;
    private static boolean wasJumpKeyPressedLastFrame = false;
    private static boolean wasShiftKeyPressedLastFrame = false;

    @SubscribeEvent
    public static void OnClientTickStart(ClientTickEvent.Pre event){
        Minecraft client = Minecraft.getInstance();
        registerAttackKeyListener(client);
    }

    // 在初始化阶段注册攻击键的按下事件监听器
    public static void registerAttackKeyListener(Minecraft client) {
            // 检查攻击键是否在当前帧被按下
            boolean isKeyPressed = client.options.keyAttack.isDown();

            // 如果攻击键在上一帧被按下而在当前帧没有被按下,表示松开了按键
            if (wasKeyPressedLastFrame && !isKeyPressed) {
                // 当攻击键被松开时执行操作
//                System.out.println("Attack key released!");
                ShieldDashMixinHelper.setIsAttackKeyPressed(false);
                BowDashMixinHelper.setIsAttackKeyPressed(false);

                // 在这里执行您的操作
            }

            // 更新攻击键上一帧的按下状态
            wasKeyPressedLastFrame = isKeyPressed;

            // 检查攻击键是否在当前帧被按下
            if (isKeyPressed) {
                // 当攻击键被按下时执行操作
//                System.out.println("Attack key pressed!");
                ShieldDashMixinHelper.setIsAttackKeyPressed(true);
                BowDashMixinHelper.setIsAttackKeyPressed(true);
                // 在这里执行您的操作
            }


            boolean isJumpKeyPressed = client.options.keyJump.isDown();
            // 如果攻击键在上一帧被按下而在当前帧没有被按下,表示松开了按键
            if (wasJumpKeyPressedLastFrame && !isJumpKeyPressed) {
                // 当攻击键被松开时执行操作
//                System.out.println("Attack key released!");
                ElytraJumpMixinHelper.setIsJumpKeyPressed(false);
                // 在这里执行您的操作
            }

            // 更新攻击键上一帧的按下状态
            wasJumpKeyPressedLastFrame = isJumpKeyPressed;

            // 检查攻击键是否在当前帧被按下
            if (isJumpKeyPressed) {
                // 当攻击键被按下时执行操作
//                System.out.println("Attack key pressed!");
                ElytraJumpMixinHelper.setIsJumpKeyPressed(true);
                // 在这里执行您的操作
            }

            boolean isShiftKeyPressed = client.options.keyShift.isDown();
            // 如果攻击键在上一帧被按下而在当前帧没有被按下,表示松开了按键
            if (wasJumpKeyPressedLastFrame && !isJumpKeyPressed) {
                // 当攻击键被松开时执行操作
//                System.out.println("Attack key released!");
                ElytraJumpMixinHelper.setIsJumpKeyPressed(false); 
                // 在这里执行您的操作
            }

            // 更新攻击键上一帧的按下状态
            wasJumpKeyPressedLastFrame = isJumpKeyPressed;

            // 检查攻击键是否在当前帧被按下
            if (isJumpKeyPressed) {
                // 当攻击键被按下时执行操作
//                System.out.println("Attack key pressed!");
                ElytraJumpMixinHelper.setIsJumpKeyPressed(true);
                // 在这里执行您的操作
            }
    }
}

利用这个按键检测的功能,做一个鞘翅如果玩家在飞行的过程中按下了,这个按键就就附加一个向上的速度


// 使用Mixin注解标记这个类,表明它将被用来注入代码到Player类中
@Mixin(Player.class)
public abstract class PlayerEntityMixin extends LivingEntity {
    // 使用@Shadow注解来声明Player类中的方法,以便在Mixin中使用
    @Shadow public abstract ItemStack getItemBySlot(EquipmentSlot slot1);

    // 声明两个用于记录上一次位置的私有变量
    @Unique
    private double lastMainPosY = 0;
    @Unique
    private double lastOffPosY = 0;
  
    // 定义一个阈值变量,用于判断位置变化是否足够大
    @Unique
    private final double THRESHOLD = 0.01; // 可以调整的阈值

    // PlayerEntityMixin的构造函数,调用父类的构造函数
    protected PlayerEntityMixin(EntityType<? extends LivingEntity> entityType, Level level) {
        super(entityType, level);
    }

    // 在Player类的tick方法执行前注入代码
    @Inject(at = @At("HEAD"), method = "tick")
    private void init(CallbackInfo ci) {
        // 获取玩家胸部装备槽中的物品
        ItemStack itemStack = this.getItemBySlot(EquipmentSlot.CHEST);
        // 检查玩家是否正在滑翔并且装备有蝴蝶附魔等级大于0
        if(this.isFallFlying() && InjectHelper.getEnchantmentLevel(itemStack, ModEnchantments.BUTTERFLY) >0){
            Player player =(Player) (Object)this;
            // 以下是被注释掉的代码,可能是用于VR环境的逻辑
            // ...
            // 如果玩家按下了跳跃键
            } else if(ElytraJumpMixinHelper.isJumpKeyPressed()){
                // 将玩家的姿态设置为站立
                this.setPose(Pose.STANDING);
                // 给玩家添加向上的推力
                this.push(0, 0.06, 0);
            }
        }
    }
}
12 获取玩家是否按了某个键
https://fuwari.vercel.app/posts/minecraft1_21_0/12_获取玩家是否按了某个键/
Author
Flandre923
Published at
2024-08-24