如何在java中记录Minecraft播放器的外观位置

时间:2017-05-17 17:58:04

标签: java eclipse minecraft-forge

我知道这个标题令人困惑。我在java中制作一个minecraft mod。当你右键单击时,我制作了一个爆炸并产生闪电的物品。目前,它在玩家的位置上爆炸并闪电。如何让它在玩家看到的位置爆炸?我的项目类目前看起来像这样:

package com.mod.elliotmod;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;

public class ItemMyTNT extends Item {

    public ItemMyTNT(String name, int stackSize) {
        GameRegistry.registerItem(this, name);
        setUnlocalizedName(ElliotMod.MODID + "_" + name);
        setCreativeTab(CreativeTabs.tabMisc);
        setMaxStackSize(stackSize);
    }

    public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player) {

        world.spawnEntityInWorld(new EntityLightningBolt(world, player.posX, player.posY, player.posZ));
        world.createExplosion(player, player.posX, player.posY, player.posZ, 5.0F, true);

        return item;
    }
}

修改 这就是我现在拥有的:

package com.mod.elliotmod;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;

public class ItemMyTNT extends Item {

    public ItemMyTNT(String name, int stackSize) {
        GameRegistry.registerItem(this, name);
        setUnlocalizedName(ElliotMod.MODID + "_" + name);
        setCreativeTab(CreativeTabs.tabMisc);
        setMaxStackSize(stackSize);
    }

    public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player) {

        double x = player.getLookVec().xCoord;
        double y = player.getLookVec().yCoord;
        double z = player.getLookVec().zCoord; 

        world.spawnEntityInWorld(new EntityLightningBolt(world, x, y, z));
        world.createExplosion(player, x, y, z, 5.0F, true);

        return item;
    }
}

我在Entity Player类中找到了这个。这可能会有所帮助

        Vec3 vec3 = new Vec3(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
        vec3 = vec3.rotatePitch(-this.rotationPitch * (float)Math.PI / 180.0F);
        vec3 = vec3.rotateYaw(-this.rotationYaw * (float)Math.PI / 180.0F);
        double d0 = (double)(-this.rand.nextFloat()) * 0.6D - 0.3D;
        Vec3 vec31 = new Vec3(((double)this.rand.nextFloat() - 0.5D) * 0.3D, d0, 0.6D);
        vec31 = vec31.rotatePitch(-this.rotationPitch * (float)Math.PI / 180.0F);
        vec31 = vec31.rotateYaw(-this.rotationYaw * (float)Math.PI / 180.0F);
        vec31 = vec31.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);

我使用过这个类,我的代码看起来像这样,但不起作用:

public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player) {
         Random rand = new Random();
         Vec3 vec3 = new Vec3(((double)rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
         vec3 = vec3.rotatePitch(-player.rotationPitch * (float)Math.PI / 180.0F);
         vec3 = vec3.rotateYaw(-player.rotationYaw * (float)Math.PI / 180.0F);
         double d0 = (double)(rand.nextFloat()) * 0.6D - 0.3D;
         Vec3 vec31 = new Vec3(((double)rand.nextFloat() - 0.5D) * 0.3D, d0, 0.6D);
         vec31 = vec31.rotatePitch(-player.rotationPitch * (float)Math.PI / 180.0F);
         vec31 = vec31.rotateYaw(-player.rotationYaw * (float)Math.PI / 180.0F);
         vec31 = vec31.addVector(player.posX, player.posY + (double)player.getEyeHeight(), player.posZ);

        MovingObjectPosition movingobjectposition = world.rayTraceBlocks(vec3, vec31, false, true, false);
        if (movingobjectposition == null) {
            //nothing was under the player's gaze
            return item;
        }
        if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
            int ix = movingobjectposition.getBlockPos().getX();
            int iy = movingobjectposition.getBlockPos().getY();
            int iz = movingobjectposition.getBlockPos().getZ();
            if (!world.isBlockNormalCube(movingobjectposition.getBlockPos(), true)) {
                --iy;
            }
            world.spawnEntityInWorld(new EntityLightningBolt(world, ix, iy, iz));
        }
        if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
            double ix = movingobjectposition.hitVec.xCoord;
            double iy = movingobjectposition.hitVec.yCoord;
            double iz = movingobjectposition.hitVec.zCoord;
            world.spawnEntityInWorld(new EntityLightningBolt(world, ix, iy, iz));
        }

        return item;


    }

1 个答案:

答案 0 :(得分:1)

所以你的第一次尝试(使用玩家的位置)是正确的一半,但是没有进入玩家所在的位置。

您正确地确定您需要使用播放器的LookVec ,但您未正确实施它。实体的LookVec是规范化的向量它不是位置。

所以你的第二次尝试仍然只有一半正确(并且在(0,0,0)的1个区块内产生闪电。

因此,要纠正错误,您需要将这两个值一起添加:

public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player) {

    double x = player.posX + player.getLookVec().xCoord;
    double y = player.posY + player.getLookVec().yCoord;
    double z = player.posZ + player.getLookVec().zCoord; 

    world.spawnEntityInWorld(new EntityLightningBolt(world, x, y, z));
    world.createExplosion(player, x, y, z, 5.0F, true);

    return item;
}

只有那部分仍然只是部分正确,因为它没有得到玩家正在看的块:它在玩家面前创造了闪电1块(嗯,实际上,我们并没有增加玩家的眼球高度。

执行 的唯一方法是进行一些光线追踪。

注意:

  • world.rayTraceBlocks_do_do的名称可能会有所不同,具体取决于您的Forge版本。我将此代码从old project中删除,需要进行一些按摩。

  • vec3:作为玩家眼睛位置的矢量

  • vec31:玩家的注视方向(以上为例)

    MovingObjectPosition movingobjectposition = world.rayTraceBlocks_do_do(vec3, vec31, false, true, false);
    if (movingobjectposition == null) {
        //nothing was under the player's gaze
        return item;
    }
    if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
        int ix = movingobjectposition.blockX;
        int iy = movingobjectposition.blockY;
        int iz = movingobjectposition.blockZ;
        if (!world.getBlock(ix, iy, iz).isNormalCube()) {
            --iy;
        }
        //spawn lightning (ix, iy, iz)
    }
    if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
        double ix = movingobjectposition.hitVec.xCoord;
        double iy = movingobjectposition.hitVec.yCoord;
        double iz = movingobjectposition.hitVec.zCoord;
        //spawn lightning (ix, iy, iz)
    }