游戏开发常见功能

游戏开发常见功能基本原理 鼠标点击产生射线 射线与模型碰撞器相交 则获取碰撞点作为子弹发射方向 4 给链接的头部施加线速度或者方向力 只依靠移动 x y 是没法真正实现物理上的移动的 只是 UI 表现上的瞬

大家好,欢迎来到IT知识分享网。

1.碰撞检测
(1)圆形和圆形的碰撞判断:计算两个圆心之间的距离是否小于两个圆的半径和
        假设圆形1的左上角坐标是(x1,y1),半径是r1;圆形2的左上角坐标是(x2,y2),半径是r2;
        用数学公式表达就是:(x1-x2)的平方+(y1-y2)的平方 < (r1+r2)的平方
//判断是否碰到道具 _proto.isHitProp = function (roleX, roleZ, roleSize) { //吃道具 var dx = Math.abs(roleX - this.x);   //返回绝对值 var dy = Math.abs(roleZ - this.z); var dis = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));   //pow(x,y) 方法可返回 x 的 y 次幂的值。//sqrt() 方法可返回一个数的平方根 var hitRadius = this.colliderSize + roleSize; if (dis <= hitRadius) { this.hitProp(); } };

(2)应用碰撞检测,做吸收金币的功能:
第一步:获取角色的位置和角色的半径大小:
var roleX = gameManager.player.getPos().x; var roleZ = gameManager.player.getPos().z; var roleY = gameManager.player.getPos().y; var roleSize = G.ROLE_SIZE;

第二步:计算角色距离金币的距离,以及计算角色和金币的半径之和:
var dx = Math.abs(roleX - this.x); var dy = Math.abs(roleZ - this.z); var dis = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));  //计算角色距离金币的距离 var hitRadius = G.GOLD_SIZE + roleSize;     //计算角色和金币的半径之和

第三步:做出碰撞检测的判断,移动金币到角色身上:
if (dis>hitRadius){     if(roleZ<this.z){        var disZ=this.z-roleZ;   //角色的位置在金币的前边        var speed = (roleX - this.x) * G.PROP_GOLD_SPEED / disZ;        this.x += speed;        this.z -= G.PROP_GOLD_SPEED;   //金币向前移动到角色身上 }else{     var disZ=roleZ-this.z;     //角色的位置在金币的后边     var speed = (roleX - this.x) * G.PROP_GOLD_SPEED / disZ;     this.x += speed;     this.z += G.PROP_GOLD_SPEED;   //金币向后移动到角色身上 }

2.通过半径之和以及中心点距离进行碰撞检测:
(1)主要检测函数:
 

/ * 检测碰撞 */ _proto.checkCollider = function (pos) { //参数是:战斗中手臂(this.battleUI.mainUI.image_collider)的中心点的全局坐标     if (this.isRemove) return;     var dx = Math.abs(pos.x - this.mainUI.x);     var dy = Math.abs(pos.y - this.mainUI.y);     var hitRadius = this.radiuSize + this.handColliderSize;     //this.radiuSize该物品的碰撞半径,物品的配表中获取该值     //this.handColliderSize 手臂碰撞区域大小 battleMgr.battleUI.getHandColliderSize函数获取==this.mainUI.image_collider.width / 2;     var dis = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); //手臂中心点和掉落物品中心点之间的直线距离     if (dis < hitRadius) { //距离小于半径之和就判断发生了碰撞         if (this.money > 0 || this.goodItem.type == G.GOOD_TYPES.NEWJINZHIBI) { //吃到纸币手机发生震动             if (this.goodItem.type == G.GOOD_TYPES.ZHIBI) {                                  utils.vibration(); //调用手机震动             } else if (this.goodItem.type == G.GOOD_TYPES.JINZHIBI) {                 utils.vibration();             } else if (this.goodItem.type == G.GOOD_TYPES.NEWJINZHIBI) {                 this.money = battleMgr.getRedBagValue();                 utils.vibration();             }         }         //吃到炸弹死亡         if (this.goodItem.type == G.GOOD_TYPES.ZHADAN) {             battleMgr.bombOver();             eventDispatcher.dispatchEvent(cc.Event.ON_GAMEOVER_CLEAR);         }         var score = this.goodScore;         //发生碰撞触发事件         eventDispatcher.dispatchEvent(cc.Event.ON_EAT_GOOD, { score: score, money: this.money, itemType: this.goodItem.type, len:         this.mainUI.x - pos.x });         // this.destroy();         this.isRemove = true;     } };

游戏开发常见功能
(2)前提准备(对手臂进行全局坐标的转换):
//碰撞检测(主要在于battleGood的碰撞检测,这里只做坐标转化而已) _prop.checkCollider = function () {     var playerHand = battleMgr.getPlayerHand(); //获取手臂碰撞点ui元素img     var point = Laya.Point.TEMP;     point.setTo(0, 0);     playerHand.localToGlobal(point); //point的值变为,手臂的本地坐标转成的全局坐标     var pos = { x: point.x + playerHand.width / 2, y: point.y + playerHand.height / 2 }; //this.battleUI.mainUI.image_collider的中心点坐标     //物件逻辑更新     var count = this.allGoods.length;     for (var i = 0; i < count; i++) {         this.allGoods[i] && this.allGoods[i].checkCollider(pos); //掉落物品的碰撞检测,调用battleGood中定义的函数     } };

3.创建遮罩,屏蔽按钮事件:
(1)创建UI元素,平铺:
游戏开发常见功能
(2)如果是box组件,必须注册一个事件:
this.mainUI.box_wating.on(Laya.Event.MOUSE_DOWN,this,function(){});

(3)设置按钮点击后,打开遮罩:
//抽奖 _proto.onChouClick = function () {     var totalScore = dataManager.getRoleScore();     var spend = dataManager.getRoleSpendScore();     if (spend > totalScore) {         // utils.prompt("积分不足");         this.mainUI.ani1.play(0, false);         return;     }     protocolReq.reqLuckDraw();     this.openWait(); }; _proto.monitorWaitTimeout = function(){     Laya.timer.once(5000,this, this.onWaitTimeOut);   // 相当于注册了一个时间点事件(定时炸弹) } _proto.cancleWaitTimeOut = function(){     Laya.timer.clear(this, this.onWaitTimeOut);  //取消定时事件的监听 }; _proto.openWait = function(){     this.mainUI.box_wating.visible = true;     this.monitorWaitTimeout();                 //注册定时事件的监听 } _proto.closeWait = function(){     this.cancleWaitTimeOut();     this.mainUI.box_wating.visible = false; }; _proto.onWaitTimeOut = function(){     if(this.mainUI.box_wating.visible)         this.closeWait();              //时间点到了,如果遮罩还在我们就执行这个函数 }

4.毫秒倒计时:
/ * 倒计时刷新 */ refreshCd = function () {     let times = this.SecondCountDown * 100; //5秒倒计时     this.countTime = window.setInterval(() => {         times = --times < 0 ? 0 : times;         var ms = Math.floor(times / 100).toString();         if (ms.length <= 1) {             ms = "0" + ms;         }         var hm = Math.floor(times % 100).toString();         if (hm.length <= 1) {             hm = "0" + hm;         }         if (times == 0) {             // alert("游戏结束");             this.ani3.play(0, true);             window.clearInterval(this.countTime);         }         // 获取分钟、毫秒数         this.ms_label.text = ms;         this.hs_label.text = hm;     }, 10); };

5.3D游戏子弹发射:
*基本原理:鼠标点击产生射线,射线与模型碰撞器相交,则获取碰撞点作为子弹发射方向;如果子弹未与3D模型相交,则直接使用射线作为发射方向
(1) 子弹获取和克隆
1. /场景中的初始子弹/ 2. public bullet: Laya.MeshSprite3D; 加载资源结束之后,获取场景中的子弹用于克隆: 1. //获取场景中的子弹用于克隆 2. this.bullet = this.scene.getChildByName("bullet") as Laya.MeshSprite3D; 3. //未产生子弹时移除克隆参考用子弹 4. this.bullet.removeSelf();

(2) 鼠标点击屏幕的位置,生成射线,射线与3D模型中的碰撞器进行碰撞检测
1. public ray: Laya.Ray = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3()); 2. /鼠标坐标/ 3. public mousePos: Laya.Vector2 = new Laya.Vector2(); 4. /碰撞信息/ 5. public rayCastHit: Laya.RaycastHit = new Laya.RaycastHit();  //不存在的接口    public rayCastHit: Laya.HitResult = new Laya.HitResult();  //存在的接口 1. //鼠标点击屏幕的位置 2. this.mousePos = new Laya.Vector2(Laya.MouseManager.instance.mouseX, Laya.MouseManager.instance.mouseY); 3. //鼠标点击屏幕产生射线 4. this.camera.viewportPointToRay(this.mousePos, this.ray); 5. //射线与3D模型中的碰撞器进行碰撞检测 6. Laya.Physics.rayCast(this.ray, this.rayCastHit, 30, 0);  //不存在的接口     this.scene.physicsSimulation.rayCast(this.ray, this.rayCastHit);   //存在的解决

(3) 进行碰撞判定,进而,在子弹脚本中设置子弹发射的方向:
1. //射击的方向向量 2. var dirV3: Laya.Vector3 = new Laya.Vector3(); 3. //如果鼠标点击到模型上(射线与碰撞器发生碰撞) 4. if (this.rayCastHit.distance !== -1) { 5.     //子弹射击方向向量 = 由鼠标点中的目标位置向量 —— 子弹起始位置向量 6.     Laya.Vector3.subtract(this.rayCastHit.position, this.bullet.transform.position, dirV3); 7.     //设置子弹控制脚本中发射方向 8.     script.setShootDirection(dirV3); 9. } else {         //如果鼠标未点击到模型上 10.     / 11.         *射线方向向量是归一化的单位向量,不能直接用于向量加减。需要根据射线产生的原理算 12.         *出相当于有长短距离的方向向量用于计算,可以通过向量缩放方法实现。 13.         *射线原理:原点是鼠标点击在近裁剪面上的点,方向是从摄像机位置到鼠标点击在远裁剪面 14.         *上的点产生的归一化方向。因此可以用摄像机到远裁面的距离模拟原始方向向量 15.     / 16.     // console.log(Laya.Vector3.scalarLength(this.ray.direction)); 17.     //摄像机到鼠标点击处的方向向量 18.     var aV3: Laya.Vector3 = new Laya.Vector3(); 19.     //根据射线方向向量、摄像机远裁剪值缩放为射线方向原始向量(使用远裁距会有一点误差,但不影响效果) 20.     Laya.Vector3.scale(this.ray.direction, this.camera.farPlane, aV3); 21.     //根据摄像机与子弹的位置求出子弹到摄像机的方向向量 22.     var bV3: Laya.Vector3 = new Laya.Vector3(); 23.     Laya.Vector3.subtract(this.camera.transform.position, this.bullet.transform.position, bV3); 24.     //射击的方向向量 = 摄像机到鼠标点击处的方向向量 +子弹到摄像机的方向向量 25.     Laya.Vector3.add(aV3, bV3, dirV3); 26.     //设置子弹控制脚本中发射方向 27.     script.setShootDirection(dirV3); 28. }

(4)  子弹控制脚本:
1. /被绑定的子弹对象/ 2. private bullet: Laya.MeshSprite3D; 3. /子弹生命周期/ 4. private life: number = 200; 5. /子弹发射的速度(方向)/ 6. public speedV3: Laya.Vector3 = new Laya.Vector3(); 1. / 2. * 设置子弹射击方向并计算速度 3. * @param directionV3 4. */ 5. public setShootDirection(directionV3: Laya.Vector3): void { 6.     / 7.     * 注: 8.     * 三维向量即是位置、方向,也可以是速度,但速度需要一个统一的参考衡量标准,比如“N*标准速度值/帧”或 9.     * “N*标准速度值/毫秒”,它类似于“N*米/帧”。 10.     * 而我们得到的方向向量,它的大小不一,无法作为标准速度值使用,这个时候可用Vector3.normalize()方法 11.     * 把任一向量归一化,产生单位为一的向量作为标准速度值,再把它进行缩放作为不同物体的速度来使用,比如 12.     * 0.2倍标准速度值,1.5倍标准速度值等,可使用Vector3.scale()方法缩放。 13.     / 14.     //将方向向量归一成单位为一的方向速度向量(在LayaAir中相当于1米的长度) 15.     Laya.Vector3.normalize(directionV3, this.speedV3); 16.     console.log("\n子弹攻击速度(方向):", this.speedV3.elements) 17.     //用缩放方法去调整发射速度,0.2倍标准速度(注:子弹速度过快,可能会越过场景中物品,不发生碰撞!) 18.     // Vector3.scale(speedV3,0.2,speedV3); 19. } 20. / 21. * 脚本帧循环更新 22. */ 23. public _update(state: Laya.RenderState): void { 24.     //子弹位置更新 25.     this.bullet.transform.translate(this.speedV3, false); 26.     //生命周期递减 27.     this.life--; 28.     //生命周期结束后,一帧后销毁子弹(目前脚本中直接销毁绑定对象会报错,后期版本解决此问题) 29.     if (this.life < 0) { 30.         Laya.timer.frameOnce(3, this, function () { this.bullet.destroy(); }); 31.     } 32. }

(5) 被子弹攻击的盒子,产生击退效果,立方体控制脚本逻辑如下:
1. /被绑定的立方体对象/ 2. public cube: Laya.MeshSprite3D; 3. /是否被攻击/ 4. private isAttacked: Boolean = false; 5. /盒子被击退的标准速度(方向)/ 6. public repelledV3: Laya.Vector3 = new Laya.Vector3(); 7. /盒子生命周期/ 8. public life: number = 60; 1. / 2. * 当其他碰撞器进入绑定物体碰撞器时触发(子弹击中盒子时) 3. * 注:如相对移动速度过快,可能直接越过 4. */ 5. public onTriggerEnter(other: Laya.Collider): void { 6.     //获取其他碰撞器绑定的模型 7.     var sp3D: Laya.MeshSprite3D = other.owner as Laya.MeshSprite3D; 8.     //获取子弹对象模型脚本 9.     var script: BulletScript = sp3D.getComponentByType(BulletScript) as BulletScript; 10.     //获取子弹速度为 11.     this.repelledV3 = script.speedV3.clone(); 12.     //被攻击速度归一化成单位一向量 13.     Laya.Vector3.normalize(this.repelledV3, this.repelledV3); 14.     //设置为被攻击状态 15.     this.isAttacked = true; 16.     console.log("\n1 子弹碰撞时位置(方向):", sp3D.transform.position.elements); 17. }

 

1. / 2. * 脚本的帧循环 3. */ 4. public _update(state: Laya.RenderState): void { 5.     //被攻击状态下,盒子产生击退效果 6.     if (this.isAttacked) { 7.         //根据击退方向和速度移动 8.         this.cube.transform.translate(this.repelledV3, false); 9.         // console.log("击退位置变化:",(this.cube.transform.position.clone() as Laya.Vector3).elements); 10.         //击退速度逐步减小 11.         Laya.Vector3.scale(this.repelledV3, 0.3, this.repelledV3); 12.         //当后退各方向速度小于0.01时,击退状态停止 13.         if (Laya.Vector3.scalarLength(this.repelledV3) < 0.01) { 14.             this.isAttacked = false; 15.         } 16.     } 17. }

6.U3D 和 Laya配合做碰撞检测,切记几点:
(1)  主动体  :空节点作为父节点的,模型作为子节点,
模型身上必须绑定 刚体和网格碰撞器,父节点不加任何物理组件
(2)  被动体: 空节点作为父节点,模型作为子节点,
模型身上必须不能带刚体,只需要加碰撞器,父节点不加任何物理组件
7.2d精灵通过绳索骨骼链接起来,链接的部分需要依靠物理引擎来运动:
(1)创建 碰撞器:
    / 创建身体的2d碰撞器 */     createCollier2d$() {         if (!this._headCtrl$) return;         this._bodyCollider$ = new Laya.CircleCollider();         this._bodyCollider$.label = "wormBody";         this._bodyCollider$.radius = this._headCtrl$.headColliderRaduis$ * this._headCtrl$.lastBodyScale$;         this._bodyCollider$.x = -this._bodyCollider$.radius + this.owner.x;         this._bodyCollider$.y = -this._bodyCollider$.radius + this.owner.y;         this.owner.addComponentIntance(this._bodyCollider$);     }

(2)创建 刚体:
  

  / 创建身体的2d刚体 */     createRigidBody2d$() {         this._bodyRigidBody$ = this.owner.addComponent(Laya.RigidBody);         this._bodyRigidBody$.allowRotation = false;         this._bodyRigidBody$.type = this.isSleep$ ? "static" : "dynamic";         this._bodyRigidBody$.body.SetGravityScale(0);     }

(3)创建 绳索骨骼:
    / 创建骨骼点 */     createRopeJoint$() {         this._bodyJoint$ = new Laya.RopeJoint();         this._bodyJoint$.otherBody = this._connectBody$;         this._bodyJoint$.selfAnchor = [0, 0];         this._bodyJoint$.otherAnchor = [0, 0];         // this._bodyJoint$.maxLength = GameSetting$.BODY_MODEL_DIS$ * GameSetting$.UI_SCENE_RATE$;         this._bodyJoint$.maxLength = GameSetting$.BODY_MODEL_DIS$;         this.owner.addComponentIntance(this._bodyJoint$);         this.updateConnectBody$();     }

(4)给链接的头部施加线速度或者方向力,只依靠移动 x,y  是没法真正实现物理上的移动的,只是UI表现上的瞬移罢了;

     _wormMove$() {         if (!this.isNeedMoved$) return;         let deltX = this.curSpeedX$ * this._deltaTime$;         let deltY = this.curSpeedY$ * this._deltaTime$;         // this._targetX$ = playerStagePos.x + deltX;         // this._targetY$ = playerStagePos.y + deltY;         let direction = new Laya.Vector2(deltX, deltY);         Laya.Vector2.normalize(direction, direction)         this.force$.x = direction.x * this.power$;         this.force$.y = direction.y * this.power$;         // playerStagePos.x = this._targetX$;         // playerStagePos.y = this._targetY$;         // this._wormX$ = playerStagePos.x;         // this._wormY$ = playerStagePos.y;         // this.owner.pos(-this._wormX$, this._wormY$);         this.setVelocity$();     }
(5)设置 物理线速度:
    setVelocity$() {         let v = this.headRigidbody$.linearVelocity;         v.x = this.force$.x;         v.y = this.force$.y;         this.headRigidbody$.linearVelocity = v;         this.headRigidbody$.applyForceToCenter(this.force$);  //施加一个力到刚体上的质心上     }

8.坐标位置,转化方向向量,计算角度:
 

        let otherPosX = this._bodyJoint$.otherBody.owner.x;  //坐标         let otherPosY = this._bodyJoint$.otherBody.owner.y;         let myPosX = this.owner.x;         let myPosY = this.owner.y;         let delX = (otherPosX - myPosX);         let delY = (otherPosY - myPosY);         let rad = Math.atan2(delY, delX);   //弧度         this.owner.rotation = rad * GameSetting$.ANGLE_1_RAD$;   //弧度转化为角度 GameSetting$.ANGLE_1_RAD$ = 180 / Math.PI;             let dx = lastButOneBody.x - lastBody.x;             let dy = lastButOneBody.y - lastBody.y;             let direction = new Laya.Vector2(dx, dy);             Laya.Vector2.normalize(direction, direction)

9.设置物体角速度使之物理系统发生旋转:
前提条件: this.sawRigidbody$.allowRotation = true;  //设置可旋转 this.sawRigidbody$.type = "dynamic";      //刚体类型动态 //旋转速度 this.rollSpeed$ = 2; setRollVelocity$() {     if (!this.woodenPlateRigidbody$ || !this.rollSpeed$) return;     this.woodenPlateRigidbody$.angularVelocity = this.rollSpeed$;    rollSpeed$  负值:逆时针  正值:顺时针 }

10.即使是3D的也可以忽略Y轴,只考虑X轴和 Z轴上的碰撞检查:

(1)基本碰撞检测,用位置和半径判断:

     /      * 行车与黑洞是否碰撞      * @param {} car      * @param {*} dinosaur      */     _isCarAndDinoCollision$(car, dinosaur) {         let hPos = car.owner.transform.position;         let dPos = dinosaur.owner.transform.position;         let x = hPos.x - dPos.x;         let z = hPos.z - dPos.z;         if (x * x + z * z <= Math.pow(dinosaur.collisionRadius + car.collisionRadius, 2)) return true;         return false;     }
(2)从数组中取出需要进行碰撞判断的 对象,嵌套for循环进行实时检测:
    /      * 检查车与黑洞碰撞      */     checkCarsAndDinoCollision$() {         if (!this._init$()) return;         if (!window.curScene || curScene.isPaused || !curScene._cars$ || !curScene.dinosaurs) return;         let cars = curScene._cars$;         let dinosaurs = curScene.dinosaurs;         let car, dinosaur;         for (let j = cars.length - 1; j >= 0; j--) {             car = cars[j];             for (let i = dinosaurs.length - 1; i >= 0; i--) {                 dinosaur = dinosaurs[i];                 if (this._isCarAndDinoCollision$(car, dinosaur)) {                     dinosaur.onCollision$(null, car);   //触发碰撞结果                     car.onKilled$(dinosaur);                     break;//一辆车只能被一只恐龙吃                 }             }         }     }

(3)注册帧循环,实时检测碰撞:
Laya.timer.loop(100, this, this.checkCarsAndDinoCollision$);

11.计算移动到目标点,需要旋转的角度:
        / 路段起始坐标 */         this._startPos$ = new Laya.Vector3();         / 路段结束坐标 */         this._endPos$ = new Laya.Vector3();         / 路线角度 */         this._roadAngle$ = undefined;         let deltaX = this._endPos$.x - this._startPos$.x;         let deltaZ = this._endPos$.z - this._startPos$.z;         this._roadAngle$ = (Math.atan2(deltaX, deltaZ) * GameSetting$.ANGLE_1_RAD$) % 360;         / 弧度转角度换算单位 */         GameSetting$.ANGLE_1_RAD$ = 180 / Math.PI;         发生旋转动画:         _move$(){             let rot = this.owner.transform.rotationEuler;             let deltaAngle = (this._roadAngle$ - rot.y) % 360;             if(deltaAngle > 180) {                 deltaAngle -= 360;             }else if(deltaAngle < -180) {                 deltaAngle += 360;             }             rot.y += deltaAngle * Math.min(0.02 * deltaT, 1);             this.owner.transform.rotationEuler = rot;         }         onUpdate(){             this._move$();         }

12.玩家交互区域判定

(1)工具函数

   /      * 获取二维距离平方 m^2      * @param {*} x1      * @param {*} y1      * @param {*} x2      * @param {*} y2      * @returns      */   static getV2DisQ$(x1, y1, x2, y2) {     return Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2);   }
(2)玩家移动状态:
 

    / 是否鼠标按下状态 */     get isMouseDown$() {         return this._isMouseDown$;     }     / 是否移动中 */     get isMoveing$() {         return this._isMoveing$;     }     / 获取上次移动时刻 ms */     get lastMouseMoveT$() {         return this._lastMouseMoveT$;     }     this.owner.on(Laya.Event.MOUSE_MOVE, this, (e: Laya.Event) => {             if (!this.currentTouch) {                 this.currentTouch = e;                 stageX = e.stageX;                 stageY = e.stageY;             } else {                 isMoved = true;                 this._lastMouseMoveT = Laya.timer.currTimer;                 this.angle = this.getAngle(new Laya.Vector2(stageX, stageY), new Laya.Vector2(e.stageX, e.stageY));                 this._isMoving = true;             }         })     / 是否等待交互 */     isWaitInteract() {         return Globals.moveCtr && !Globals.moveCtr.isMouseDown && Globals.moveCtr.lastMouseMoveT > 0 && Globals.moveCtr.lastMouseMoveT + 300 < Laya.timer.currTimer;     }

(3)主逻辑代码
 

    //交互距离平方     public interDisQ: number = 1.5 * 1.5; onUpdate() {         this.checkInteract();     }     checkInteract(): void {         if (!this.playerMove) return;         let playerPos = this.playerMove.position;         let disQ = Utils.getV2DisQ$(playerPos.x, playerPos.z, this.boxAreaPos.x, this.boxAreaPos.z);         (disQ > this.interDisQ || !this.playCtr.isWaitInteract()) ? this.onNoInter() : this.onInter();  //!this.playCtr.isWaitInteract()可注释     }     onInter(): void {         if (this._isInter) return;         this._isInter = true;         console.log("tcy 进去食品交互区域")     }     onNoInter(): void {         if (!this._isInter) return;         this._isInter = false;         console.log("tcy 离开食品交互区域")     }

13.是否在交互矩形范围内

     /      * 点是否在矩形范围内(场景是平面(非球形),只取X和Z方向坐标)      * @param {*} pV3  坐标点      * @param {*} tV3  目标坐标点      * @param {*} xR   目标x长度/2      * @param {*} zR   目标z长度/2      */     static isInRect$(pV3, tV3, xR, zR) {         if (pV3.x > tV3.x - xR && pV3.x < tV3.x + xR && pV3.z > tV3.z - zR && pV3.z < tV3.z + zR) return true;         return false;     }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/139082.html

(0)
上一篇 2025-06-08 18:15
下一篇 2025-06-08 18:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信