如何使用非原始变量设置对象位置,修复JS拖拽圆形脚本问题
代码问题排查与修复
存在的核心问题
- 事件注册逻辑错误:
mouseDragMethod、mouseMoveMethod属于事件监听器注册API,不可放在定时器中重复调用,仅需初始化时执行一次即可,重复注册会导致逻辑混乱、函数重复触发。 - 圆坐标获取逻辑错误:调用
getVariableXAndY获取圆心坐标时,没有传入对应的circle1/2/3对象,无法拿到正确的圆心坐标。 - 碰撞检测逻辑错误:
- 检测逻辑误将Y轴坐标与mouseX做对比,完全不符合点在圆形内的判定逻辑(正确逻辑应为:鼠标点与圆心的距离小于等于半径)
- 存储坐标的
val数组结构嵌套错误,取值时层级不对
- 变量拼写错误:
mouseMoveBall函数中oldMouse为拼写错误,应为oldMouseX - 拖拽逻辑缺失:仅计算了鼠标偏移量,没有记录当前被选中的拖拽对象,也没有将偏移量应用到对应圆的位置更新上
- 定时器使用冗余:拖拽逻辑完全可以通过事件驱动实现,不需要用定时器轮询检测状态,徒增性能损耗和逻辑复杂度
修复后的可运行代码
var NUM_CIRCLES = 3; var RADIUS = 30; var mouseX = 0; var mouseY = 0; // 新增变量:记录当前被拖拽的圆、鼠标按下时与圆心的偏移量 var selectedCircle = null; var offsetX = 0; var offsetY = 0; var circles = []; // 用数组存储所有圆,方便后续遍历 function start(){ drawCircles(); // 初始化时注册一次事件即可 mouseDownMethod(onMouseDown); mouseMoveMethod(onMouseMove); mouseUpMethod(onMouseUp); } function drawCircles() { // 用循环生成圆,避免重复代码 for(var i = 0; i < NUM_CIRCLES; i++){ var circle = new Circle(RADIUS); var x = Randomizer.nextInt(RADIUS, getWidth() - RADIUS); var y = Randomizer.nextInt(RADIUS, getHeight() - RADIUS); circle.setPosition(x, y); circle.setColor(Randomizer.nextColor()); add(circle); circles.push(circle); } } // 鼠标按下事件:检测是否点中圆,记录选中状态和偏移量 function onMouseDown(e){ mouseX = e.getX(); mouseY = e.getY(); // 倒序遍历,确保点中重叠的圆时,选中最上层的 for(var i = circles.length - 1; i >= 0; i--){ var circle = circles[i]; var cx = circle.getX(); var cy = circle.getY(); // 点在圆内判定:两点距离平方小于等于半径平方(避免开方提升性能) var dx = mouseX - cx; var dy = mouseY - cy; if(dx * dx + dy * dy <= RADIUS * RADIUS){ selectedCircle = circle; offsetX = dx; offsetY = dy; break; } } } // 鼠标移动事件:如果有选中的圆,更新圆的位置 function onMouseMove(e){ if(!selectedCircle) return; var newX = e.getX() - offsetX; var newY = e.getY() - offsetY; // 可选:限制圆不超出画布边界 newX = Math.max(RADIUS, Math.min(newX, getWidth() - RADIUS)); newY = Math.max(RADIUS, Math.min(newY, getHeight() - RADIUS)); selectedCircle.setPosition(newX, newY); } // 鼠标松开事件:清空选中状态 function onMouseUp(){ selectedCircle = null; }
内容的提问来源于stack exchange,提问作者Lerb_games school alt
相关产品推荐
相关产品推荐

