JavaScript射线投射碰撞异常问题排查求助
穿墙射线投射碰撞异常排查求助
我正在实现穿墙射线投射功能,每条射线包含碰撞对象(objectHIT)和交点坐标(pointIntersectionXY)信息。目前已完成射线投射,但碰撞效果并非总能符合预期,反复检查代码仍未定位问题。已确认碰撞计算函数生成的listCollision中,交点坐标及其他属性均准确无误,现将相关函数代码附上,请求协助排查问题:
代码注释说明
listCollision[射线索引][被碰撞对象]:存储每条射线的所有碰撞点信息VisaoLimitada[射线索引]:存储每条射线的起点与终点坐标
limitDistance(listCollision, visaoLimitada) { for (let i = 0; i < this.laser; i++) { var distanciaV = { x1: visaoLimitada[i].x1, y1: visaoLimitada[i].y1, x2: visaoLimitada[i].x2, y2: visaoLimitada[i].y2 }; var originDistance = this.distanceC(distanciaV.x1, distanciaV.x2, distanciaV.y1, distanciaV.y2); // 计算射线全长 for (let j = 0; j < listCollision[i].length; j++) { var distanciaAtingida = { x1: distanciaV.x1, y1: distanciaV.y1, x2: listCollision[i][j].x, y2: listCollision[i][j].y }; var objectDistance = this.distanceC(distanciaAtingida.x1, distanciaAtingida.x2, distanciaAtingida.y1, distanciaAtingida.y2); if(objectDistance < originDistance){ visaoLimitada[i] = distanciaAtingida; originDistance = visaoLimitada[i]; // 用于查找更近的下一个对象 } } } return visaoLimitada; } calculateViewport(FOV){ var intervaloX = (this.player[3].x - this.player[1].x)/this.laser; var intervaloY = (this.player[3].y - this.player[1].y)/(this.laser-1); // 游戏循环中先调用calculateViewport()初始化射线为直线,再传入listCollisions更新碰撞后的射线坐标 if(FOV == null || this.isEmpty(FOV) == 1){ for(let i = 0; i < this.laser; i++){ this.visao[i].x1 = this.player[1].x + 1*Math.cos(this.radians(this.aX)) + i * intervaloX; this.visao[i].y1 = this.player[1].y + 1*Math.sin(this.radians(this.aX)) + i * intervaloY; this.visao[i].x2 = this.player[1].x + this.distanceView*Math.cos(this.radians(this.aX)) + i * intervaloX; this.visao[i].y2 = this.player[1].y + this.distanceView*Math.sin(this.radians(this.aX)) + i * intervaloY; } } else{ this.visao = this.limitDistance(FOV, this.visao); } }
核心问题排查与修正建议
originDistance变量更新错误
原代码中找到更近的碰撞点后,错误地将visaoLimitada[i](坐标对象)赋值给了存储距离数值的originDistance,导致后续距离比较完全失效。修正为更新为当前碰撞点的距离值:if(objectDistance < originDistance){ visaoLimitada[i] = distanciaAtingida; originDistance = objectDistance; // 替换为当前近点的距离值 }射线起点偏移可能引发的问题
calculateViewport中射线起点x1/y1的计算额外添加了1*Math.cos(...)和1*Math.sin(...),如果这个1是无意义的偏移,会导致射线起点偏离玩家位置,进而影响碰撞距离计算的准确性。建议验证该偏移的必要性,若无需则移除。intervaloY分母的边界问题
当射线数量this.laser为1时,(this.laser-1)会导致除以0的错误。建议统一分母为this.laser,或添加边界判断避免异常:var intervaloY = (this.player[3].y - this.player[1].y)/(this.laser > 1 ? this.laser-1 : 1);碰撞点未排序的潜在隐患
若listCollision[i]中的碰撞点未按距离从近到远排序,当前遍历逻辑虽然能找到最近点,但效率较低。建议在生成listCollision时先对每条射线的碰撞点按距离排序,减少无效比较。
内容的提问来源于stack exchange,提问作者Dalton Gomes
相关产品推荐
相关产品推荐

