Minecraft里的射线与方块碰撞检测算法

觉得挺有用的就自己花时间研究了下,手动做了反混淆,顺便去掉了一些无用代码

这个函数在Minecraft中很多地方都用到了,比如判断鼠标正指向哪个方块哪个面,还有判断射出去的箭是否撞到了方块


这个函数返回从起始点到结束点这条射线碰撞到的第一个方块

    // 参数:起始点,结束点,不忽略液体,忽略非固体方块
    public MovingObjectPosition rayTraceBlocks_do_do(Vec3 start, Vec3 end, boolean fluid, boolean noNonSolid)
    {
        if (!Double.isNaN(start.xCoord) && !Double.isNaN(start.yCoord) && !Double.isNaN(start.zCoord))
        {
            if (!Double.isNaN(end.xCoord) && !Double.isNaN(end.yCoord) && !Double.isNaN(end.zCoord))
            {
                // 终点方块坐标
                int intX2 = MathHelper.floor_double(end.xCoord);
                int intY2 = MathHelper.floor_double(end.yCoord);
                int intZ2 = MathHelper.floor_double(end.zCoord);
                // 起点(当前)方块坐标
                int intX1 = MathHelper.floor_double(start.xCoord);
                int intY1 = MathHelper.floor_double(start.yCoord);
                int intZ1 = MathHelper.floor_double(start.zCoord);
  
                // 检测起点方块
                int id = this.getBlockId(intX1, intY1, intZ1);
                int data = this.getBlockMetadata(intX1, intY1, intZ1);
                Block block = Block.blocksList[id];
  
                if (block != null && (!noNonSolid || block == null || block.getCollisionBoundingBoxFromPool(this, intX1, intY1, intZ1) != null) && id > 0 && block.canCollideCheck(data, fluid))
                {
                    MovingObjectPosition movingobjectposition = block.collisionRayTrace(this, intX1, intY1, intZ1, start, end);
  
                    if (movingobjectposition != null)
                    {
                        return movingobjectposition;
                    }
                }
  
                id = 200; // 最多检测201个方块
  
                while (id-- >= 0)
                {
                    if (Double.isNaN(start.xCoord) || Double.isNaN(start.yCoord) || Double.isNaN(start.zCoord))
                    {
                        return null;
                    }
                    // 检测了终点方块
                    if (intX1 == intX2 && intY1 == intY2 && intZ1 == intZ2)
                    {
                        return null;
                    }
  
                    // 起点(当前)方块和终点方块XYZ不同(向某方向选了候选方块)
                    boolean Xchanged = true;
                    boolean Ychanged = true;
                    boolean Zchanged = true;
                    // 各方向候选方块坐标
                    double newX;
                    double newY;
                    double newZ;
  
                    // 尝试向X方向选候选方块
                    if (intX2 > intX1)
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值