cocos creator 不用物理系统,自己检测碰撞遇到的坑

这是官方给的碰撞出发回调 ,other和self分别代表碰撞的对方node,和我的node 

node中包含了world.aabb,是碰撞框,方便计算用的,里边有一些属性

onCollisionStay(other, self) {

        //console.log('on collision enter');

        // 碰撞系统会计算出碰撞组件在世界坐标系下的相关的值,并放到 world 这个属性里面

        var world = self.world;

        // 碰撞组件的 aabb 碰撞框

        var aabb = world.aabb;

        // 节点碰撞前上一帧 aabb 碰撞框的位置

        var preAabb = world.preAabb;

        // 碰撞框的世界矩阵

        var t = world.transform;

        // console.log("------世界碰撞区域-----", t, aabb.x, aabb.y, aabb.width, aabb.height);

        // 以下属性为圆形碰撞组件特有属性

        var r = world.radius;

        var p = world.position;

}

作为以前写unity的我来说,一直认为 aabb中的x,y是碰撞框的中心点,导致计算碰撞错误

至于x,y具体表示碰撞框什么情况下的位置,我也不得而知了

下面这个如图是aabb中的数据,-112,870是aabb.center中的坐标,也就是碰撞框的中心点,

下面的x:-161,y:829是aabb.x  aabb.y的位置

这两个位置是差别还是有不少呢

这个导致我计算是否碰撞一直出错

一开始是用中心点加宽的一半,计算出最大x,其实这里aabb.xMax就是最大x

还有xMinx,xMiny等等都是提供好的

写这篇的目的主要是要记住这次教训

至于为什么aabb中的x,y和center不一样,希望有知道的朋友可以在下方解释一下,谢谢啦

最后贴上我自己计算角色碰撞后回弹的代码

            let otherR = other.world.aabb.xMax;// 碰撞物的右边x

            let otherL = other.world.aabb.xMin;// 碰撞物的左边x

            let otherU = other.world.aabb.yMax;// 碰撞物的上边x

            let otherD = other.world.aabb.yMin;// 碰撞物的下边x

            let myR = self.world.aabb.xMax;// 我的右边x

            let myL = self.world.aabb.xMin// 我的左边x

            let myU = self.world.aabb.yMax;// 我上边x

            let myD = self.world.aabb.yMin;// 我的下边x

            if(this.lookAt===GameConfig.RoleDirection.left|| this.lookAt === GameConfig.RoleDirection.right)

            {// 角色当前朝向是左或者右

                if((myR-otherL>=0&&myR-otherL<60)||(otherR-myL>=0&&otherR-myL<60))

                {// 我的最大x大于他的最小x,右侧撞到// 他的最大x大于我的最小x,左侧撞到

                    dir = this.lookAt; // 记录撞到的方向

                }

                // 没有找到方向

                if(dir===GameConfig.RoleDirection.none)

                {

                   // 还要看看上下方向有没有撞到

                    if(myU-otherD>=0&&myU-otherD<60)

                    {// 我的最大y大于他的最小y,上侧撞到

                        dir = GameConfig.RoleDirection.up;

                    }

                    if(otherU-myD>=0&&otherU-myD<60)

                    {// 他的最大y大于我的最小y,下侧撞到

                        dir = GameConfig.RoleDirection.down;

                    }

                }

            }

            if(this.lookAt===GameConfig.RoleDirection.up|| this.lookAt === GameConfig.RoleDirection.down)

            {// 角色当前朝向是上或者下

                if((myU-otherD>=0&&myU-otherD<60)||(otherU-myD>=0&&otherU-myD<60))

                {// 我的最大y大于他的最小y,上侧撞到//他的最大y大于我的最小y,下侧撞到

                    dir = this.lookAt;

                }

                

                if(dir===GameConfig.RoleDirection.none)

                {// 左右方向没有撞到

                    // 还要看看左右方向有没有撞到

                    if(myR-otherL>=0&&myR-otherL<60)

                    {// 我的最大x大于他的最小x,右侧撞到

                        dir = GameConfig.RoleDirection.right;

                    }

                    if(otherR-myL>=0&&otherR-myL<60)

                    {// 他的最大x大于我的最小x,左侧撞到

                        dir = GameConfig.RoleDirection.left;

                    }

                }

            }

                先根据角色当前朝向,确定是不是当前方向撞了,如果不是当前方向,再判断另外两个方向是不是撞到了,这样记录dir是撞到的方向

然后得到与dir相反的方向,让角色往dir反方向回弹一下,这里的代码是碰撞的回调,只要有接触碰撞,就回弹一下,直到没有接触

这里是因为帧同步不能用物理系统自己检测碰撞,不同机型会产生误差,所以需要自己根据碰撞器计算是否撞到了,但是这个回弹效果也没有办法,因为是撞到后

才能判断,不能让角色擦其他障碍物走,所以肯定要回弹一下,回弹后再让角色继续走,撞到的时候记录这个方向是不能走的,可能另外两个方向也擦着边,可能只有反方向可以走

回弹期间不可以走

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值