你是否想在MC中实现一个效果,当你按下一个键的时候就会触发一个特殊效果(召唤、获得一个buff、传送到一个地点),我们今天就着手实现MC中的键位控制。
1.Java包中新建一个keys包 -> keys包中新建ModKeyBinding类
ModKeyBinding.java
package com.joy187.rejoymod.keys;
import com.joy187.rejoymod.IdlFramework;
import com.joy187.rejoymod.proxy.ClientProxy;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.client.settings.IKeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
//@SideOnly(Side.CLIENT)
public class ModKeyBinding extends KeyBinding {
public ModKeyBinding(String description, IKeyConflictContext keyConflictContext, KeyModifier keyModifier, int keyCode, String category) {
super(String.format("key.%s.%s", IdlFramework.MODID, description), keyConflictContext, keyModifier, keyCode, category);
//将模组中所有键位进行注册
ClientProxy.KEY_BINDINGS.add(this);
}
}
2.找到我们的ClientProxy类,添加模组所有键位的信息:
ClientProxy.java
package com.joy187.rejoymod.proxy;
import com.joy187.rejoymod.init.ModParticles;
import com.joy187.rejoymod.keys.ModKeyBinding;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.item.Item;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
import org.lwjgl.input.Keyboard;
import java.util.ArrayList;
import java.util.List;
public class ClientProxy extends ProxyBase {
public static final List<KeyBinding> KEY_BINDINGS = new ArrayList<KeyBinding>();
//我们所有的键位进行声明 参数最重要的是Keyboard.KEY_X 对应我们的按键,其他基本不变
public static final KeyBinding SUMMON = new ModKeyBinding("activate_skill_summon", KeyConflictContext.IN_GAME, KeyModifier.NONE, Keyboard.KEY_V, "key.category.rejoymod");
public static final KeyBinding EFFECTME = new ModKeyBinding("activate_skill_effectme", KeyConflictContext.IN_GAME, KeyModifier.NONE, Keyboard.KEY_R, "key.category.rejoymod");
public boolean isServer()
{
return false;
}
public void registerItemRenderer(Item item, int meta, String id)
{
ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName(), id));
}
@Override
public void registerParticles() {
ModParticles.registerParticles();
}
}
3.在keys包中新建KeyboardManager类用于管理键位事件(按下相应键后会发生什么):
我们想让自己按下R键后有个随机传送的效果:
KeyboardManager.java
package com.joy187.rejoymod.keys;
import com.joy187.rejoymod.IdlFramework;
import com.joy187.rejoymod.item.ModItems;
import com.joy187.rejoymod.item.skills.ItemSkillBase;
import com.joy187.rejoymod.network.NetworkHandler;
import com.joy187.rejoymod.network.protocols.PacketTest;
import com.joy187.rejoymod.proxy.ClientProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Random;
//@SideOnly(Side.CLIENT)
@Mod.EventBusSubscriber
public class KeyboardManager {
//ref: https://harbinger.covertdragon.team/chapter-18/keyboard.html
public static void init() {
for (KeyBinding key:
ClientProxy.KEY_BINDINGS) {
ClientRegistry.registerKeyBinding(key);
}
IdlFramework.Log("Registered %d keys", ClientProxy.KEY_BINDINGS.size());
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public static void onKeyPressed(InputEvent.KeyInputEvent event) {
//当按下EFFECTME键(V键)时
if (ClientProxy.EFFECTME.isPressed()) {
Minecraft mc = Minecraft.getMinecraft();
EntityPlayerSP player = mc.player;
if(player == null) return;
if(mc.isGamePaused()) return;
if(!mc.inGameHasFocus) return;
if(mc.currentScreen != null) return;
EnumHand hand = ClientProxy.EFFECTME.isKeyDown() ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND;
IdlFramework.Log("pressed key cast :" + hand);
Random ran = new Random();
//玩家以20为半径随机传送
player.setPosition(player.getPositionVector().x+ran.nextInt(20),player.getPositionVector().y,player.getPositionVector().z+ran.nextInt(20));
//mc.playerController.updateController();
// NetworkManager.channel.sendToServer(new C2SSpecialAction((byte) 1));
}
}
}
药水效果可以使用addPotionEffect
函数实现:
//给予5s凋零效果
palyer.addPotionEffect(new PotionEffect(MobEffects.WITHER, 20*5));
找到我们的Main类,在init函数中添加KeyboardManager的初始化信息:
@EventHandler
public static void Init(FMLInitializationEvent event) {
//添加键位初始化信息,我们的按键效果只在客户端生效
if (!proxy.isServer())
{
KeyboardManager.init();
}
}
4.当穿上盔甲后按下键实现召唤生物的效果,我们可以找到自己的盔甲类,以ArmorMirandaSuit为例:
我们要找到一个函数onArmorTick
,它有检测我们是否穿上了盔甲的作用
ArmorMirandaSuit.java
package com.joy187.rejoymod.item.armor;
import com.joy187.rejoymod.IdlFramework;
import com.joy187.rejoymod.entity.EntityEthan;
import com.joy187.rejoymod.entity.EntityGaia;
import com.joy187.rejoymod.entity.EntityM1851B;
import com.joy187.rejoymod.entity.ModEntityInit;
import com.joy187.rejoymod.entity.projectiles.ProjectileArgs;
import com.joy187.rejoymod.item.ModItems;
import com.joy187.rejoymod.proxy.ClientProxy;
import com.joy187.rejoymod.util.IHasModel;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityEvoker;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityEvokerFangs;
import net.minecraft.entity.projectile.EntityWitherSkull;
import net.minecraft.init.MobEffects;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemMonsterPlacer;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class ArmorMirandaSuit extends ItemArmor implements IHasModel {
public ArmorMirandaSuit(String name, CreativeTabs tab, ItemArmor.ArmorMaterial materialIn, EntityEquipmentSlot equipmentSlotIn) {
super(materialIn, 1, equipmentSlotIn);
setUnlocalizedName(name);
setRegistryName(name);
setCreativeTab(tab);
setMaxStackSize(1);
ModItems.ITEMS.add(this) ;
}
@Override
public void registerModels() {
IdlFramework.proxy.registerItemRenderer(this, 0, "inventory");
}
@Override
public ModelBiped getArmorModel(EntityLivingBase entity, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped _default) {
if(!itemStack.isEmpty())
{
if(itemStack.getItem() instanceof ItemArmor)
{
MirandaSuit model = new MirandaSuit();
model.bone.showModel = armorSlot == armorSlot.CHEST;
// model.LeftArm.showModel = armorSlot == armorSlot.CHEST;
// model.RightArm.showModel = armorSlot == armorSlot.CHEST;
model.leftArmPose = _default.leftArmPose;
model.rightArmPose = _default.rightArmPose;
model.isChild = _default.isChild;
model.isRiding= _default.isRiding;
model.isSneak = _default.isSneak;
return model;
}
}
return null;
//.applyEntityStats(defaultArmor).applySlot(EquipmentSlotType.HEAD);
}
@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
if(player.inventory.armorItemInSlot(2).getItem() == ModItems.MIRANDASUIT &&
player.inventory.armorItemInSlot(2)!=null) {
//如果要穿上好几件才能触发按键效果的话,你可以把这些都加入到上面的if判断中
//护腿:player.inventory.armorItemInSlot(1).getItem() == ModItems.FRANK_LEG && player.inventory.armorItemInSlot(1)!=null
//头盔:player.inventory.armorItemInSlot(3).getItem() == ModItems.FRANK_HEAD && player.inventory.armorItemInSlot(3)!=null
//靴子:player.inventory.armorItemInSlot(0).getItem() == ModItems.FRANK_BOOTS && player.inventory.armorItemInSlot(0)!=null
effectPlayer(player, MobEffects.HASTE, 0, 3);
effectPlayer(player, MobEffects.REGENERATION, 0, 3);
//此时当我们按下SUMMON键(R键),就会生成一个凋零骷髅头
if(ClientProxy.SUMMON.isPressed())
{
world.playEvent((EntityPlayer)null, 1024, new BlockPos(player), 0);
double d0 = player.getLookVec().x;
double d1 = player.getLookVec().y;
double d2 = player.getLookVec().z;
double d3 = player.posX-d0;
double d4 = player.posY-d1;
double d5 = player.posZ-d2;
EntityWitherSkull e = new EntityWitherSkull(world, player, d0, d1, d2);
//主世界生成骷髅头
player.world.spawnEntity(e);
}
}
super.onArmorTick(world, player, itemStack);
}
private void effectPlayer(EntityPlayer player, Potion effect, int duration, int amplifier) {
if(player.getActivePotionEffect(effect)==null || player.getActivePotionEffect(effect).getDuration() <=1) {
player.addPotionEffect(new PotionEffect(effect, duration, amplifier, false, true));
}
}
}
5.保存所有文件 -> 进入游戏调试
没有穿上胸甲,按下R键,没有反应