我知道这个标题令人困惑。我在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;
}
答案 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)
}