网格约束移动问题:椭圆移动时触发新指令偏离网格的修复问询
问题修复:移动过程中触发新指令导致椭圆偏离网格
问题说明
椭圆移动时触发新的移动指令,会偏离网格,且后续一直处于非网格中心状态,直到抵达目标。需要保留覆盖原有指令的能力,同时让椭圆先回到当前网格方块中心,再执行新的移动指令。
解决方案
核心是新增状态控制,让椭圆在接收新指令前先回到网格中心,之后再执行新目标的移动。以下是修改后的完整代码:
// 变量初始化 // p:当前玩家位置 var pX = 210; var pY = 210; // m:最终移动目标 var mX = 210; var mY = 210; // tempTarget:临时目标(用于回到网格中心) var tempTargetX = pX; var tempTargetY = pY; // s:当前位置对应的网格中心坐标 var sX = 0; var sY = 0; // 状态标记:是否正在返回网格中心 var isReturningToGrid = false; // 坐标取整函数(对齐网格) function roundNum(number, increment, offset) { return Math.ceil((number - offset) / increment ) * increment + offset; } // 鼠标点击事件 mouseClicked = function() { // 计算新的目标网格坐标 var newTargetX = roundNum(mouseX-10,20,10); var newTargetY = roundNum(mouseY-10,20,10); // 如果当前不在网格中心,先设置临时目标为当前网格中心 if (pX !== sX || pY !== sY) { tempTargetX = sX; tempTargetY = sY; isReturningToGrid = true; // 保存最终目标,等回到网格后再执行 mX = newTargetX; mY = newTargetY; } else { // 已经在网格中心,直接设置新目标 mX = newTargetX; mY = newTargetY; isReturningToGrid = false; } }; draw = function() { // 绘制基础背景和网格坐标计算 background(255, 255, 255); sX = roundNum(pX,20,10); sY = roundNum(pY,20,10); // 绘制网格 stroke(0, 0, 0); fill(255, 255, 255); // 垂直线 for(let x=20; x<=380; x+=20){ line(x, 0, x, 400); } // 水平线 for(let y=20; y<=380; y+=20){ line(0, y, 400, y); } // 绘制目标点 noStroke(); fill(18, 235, 33); ellipse(mX,mY,10,10); // 移动逻辑:优先处理回到网格中心 if(isReturningToGrid){ // 回到临时目标(网格中心) if(pX < tempTargetX) pX += 1; else if(pX > tempTargetX) pX -= 1; if(pY < tempTargetY) pY += 1; else if(pY > tempTargetY) pY -= 1; // 到达网格中心后,切换到执行最终目标 if(pX === tempTargetX && pY === tempTargetY){ isReturningToGrid = false; } } else { // 执行最终目标的移动 if(pX < mX) pX += 1; else if(pX > mX) pX -= 1; if(pY < mY) pY += 1; else if(pY > mY) pY -= 1; } // 绘制玩家椭圆 noStroke(); fill(0, 0, 0); ellipse(pX,pY,10,10); // 边界限制 pX = constrain(pX, 10, 390); pY = constrain(pY, 10, 390); // 调试信息 noStroke(); fill(235, 235, 235); quad(0,0,75,0,75,140,0,140); fill(0, 0, 0); text("pX = "+pX,10,10); text("pY = "+pY,10,25); text("mX = "+mX,10,55); text("mY = "+mY,10,70); text("sX = "+sX,10,115); text("sY = "+sY,10,130); text("返回状态:"+isReturningToGrid,10,145); };
关键改动说明
- 新增状态与临时目标:添加
isReturningToGrid标记和tempTargetX/Y变量,用于控制椭圆先回到网格中心的逻辑。 - 鼠标点击逻辑优化:点击时先判断椭圆是否在网格中心,不在则先设置临时目标为当前网格中心,同时保存最终目标;在中心则直接设置新目标。
- 移动逻辑重构:draw函数中优先处理回到网格中心的移动,完成后再切换到最终目标的移动,确保椭圆始终在网格对齐的状态下执行新指令。
- 网格绘制简化:用循环替代重复的line语句,精简代码。
- 边界处理优化:使用
constrain函数简化边界限制代码。
内容的提问来源于stack exchange,提问作者Aceae
相关产品推荐
相关产品推荐

